The following is a post explaining the functionality of a C# program in Visual Studio, which is designed to do basic operations between fractions which are ratios of whole numbers.

To begin, three namespaces are included using the “using” directive statement.

The “system” namespace is included with every program. The next two must be included to implement certain classes. Without the directives in place, these namespaces would have to be included manually with every usage of the classes that are a part of them.

The next bit of code is pictured above. Two integers are created with a “private” access modifier to indicate they can only be used within the Fraction class. Next, the constructor for Fraction is called and supplied with the two integers. The “this” keyword uses the current instance of the class to assign one of the inputs (num) to a member of the class. “This” can be helpful to distinguish between constructor inputs and members of the class since “this” always refers to members of the current instance. An “if” statement is included to handle exceptions thrown by having a denominator of zero. You can always identify a constructor by its lack of a data type.

For some reason, the constructor should be called again, and it should inherit itself (???) with a 0 and 1 supplied as its argument. God only knows why.

The Reduce function is meant to reduce the fraction to its canonical (simplest) form. It is important to note that the method is private, which means that it cannot be used outside the class “Fraction”. The greatest common denominator is initialized to zero. A for loop is executed to cycle through all the way to what “denomenator” is used for. Denomenator is allowed to be used here because the method is used within the class. Successive division is used to check if the canonical form has been achieved. By dividing by the loop index and checking for a remainder of zero for both the numerator and denominator, it can be shown whether more division should be done or not. If both conditions are true, the greatest common denominator has been found to be the loop index. The next step is to divide the numerator and denominator through by this value. For example, if the numerator was set to 3 and the denominator was set to 6, by the time the loop counter reached three, both statements would return a boolean “TRUE” and the gcd would be set to 3. Then both values would be divided by 3, reducing the fraction to 1/2.

The next step is to define the properties. Properties allow private variables to be used publicly. This can be useful when you need to protect certain data by not allowing it to be used in any class, but sometimes needs to be exposed. This is accomplished using “getters” and “setters”. The “value” keyword is automatically provided when using a “setter” and sets the private variable to that value. Basically, numerator and denomenator are private variables and can only be changed within the class. Encapsulation refers to the scope of members within classes or structs. Properties provide a flexible way to control the accessibility of these members.

The last method is used to convert integer fractions to the double data type. This functionality is provided by the “explicit” keyword. The result is a returned “fractiondecimal” of data type double.

The following codes are suppressed using the “#region” keyword. By entering each region, the code can be viewed. Within the first block of code, the custom arithmetic operators are defined, two of which are shown below.

The addition is slightly complicated, because a common denominator must be found. Different implementations of the Fraction class are supplied to the input of the operator method. The fields “numerator” and “denomenator” are accessed through the class and assigned to a variable. A new object (“c”) is instantiated from the Fraction class which is the sum of “a” and “b”. The multiplication custom operator is slightly simpler, because it is straight across multiplication. Additional code is provided to change the sign of both the numerator and denominator if the denominator is negative. The operators for division and subtraction employ similar logic.

The comparison operators are defined using the same common denominator technique. The only difference between each operator method is the symbol used in the “if” statement. Six methods are provided (<, >, ==, !=, >= and <=).

The last bit of code is pictured below. The “ToString” method is inherited by every class and therefore can be overridden. This allows flexibility to define the “ToString” method however you want. In this case, we want a fraction to be printed. The “as” keyword can convert between nullable or reference types and returns null if the conversion is not possible. When this conversion from obj to Fraction is possible, the numerator and denominator are set and the fraction is returned.