Using the operator Keyword






Using the operator Keyword

In C#, operators are static methods. The return value of an operator represents the result of an operation. The operator's parameters are the operands.

Thus, to create an addition operator for a Fraction class, you use the C# syntax of combining the operator keyword with the plus sign (+) operator combined with the keyword static. For example, the overloaded addition operator (the operator+ method) takes two Fraction objects (the fractions you want to add) as parameters and returns a reference to another Fraction object representing the sum of the two parameters. Here is its signature:

    public static Fraction operator+(Fraction lhs, Fraction rhs)

And here's what you can do with it. Assume, for instance, you've defined two fractions representing the portion of a pie you've eaten for breakfast and lunch, respectively. (You love pie.)

    Fraction pieIAteForBreakfast = new Fraction(1,2); // 1/2 of a pie
    Fraction pieIAteForLunch = new Fraction(1,3);     // 1/3 of a pie

The overloaded operator+ allows you to figure out how much pie you've eaten in total. (And there's still 1/6 of a pie left over for dinner!) You write:

    Fraction totalPigOut = pieIAteForBreakfast + pieIAteForLunch;

The compiler takes the first operand (pieIAteForBreakfast) and passes it to operator+ as the parameter lhs; it passes the second operand (pieIAteForLunch) as rhs. These two Fractions are then added, and the result is returned and assigned to the Fraction object named totalPigOut.

It is my convention to name the parameters to a binary operator lhs and rhs. A binary operator is an operator that takes two operands. The parameter name lhs stands for "lefthand side" and reminds me that the first parameter represents the lefthand side of the operation. Similarly, rhs stands for "righthand side."


To see how this works, you'll create a Fraction class, as described previously. The complete listing is shown in Figure, followed by a detailed analysis.

Implementing operator+ for Fraction

using System;

public class Fraction
{
   private int numerator;
   private int denominator;

   // create a fraction by passing in the numerator
   // and denominator
   public Fraction( int numerator, int denominator )
   {
      this.numerator = numerator;
      this.denominator = denominator;
   }

   // overloaded operator + takes two fractions
   // and returns their sum
   public static Fraction operator+( Fraction lhs, Fraction rhs )
   {
      // like fractions (shared denominator) can be added
      // by adding their numerators
      if ( lhs.denominator == rhs.denominator )
      {
         return new Fraction( lhs.numerator + rhs.numerator,
         lhs.denominator );
      }

      // simplistic solution for unlike fractions
      // 1/2 + 3/4 == (1*4) + (3*2) / (2*4) == 10/8
      // this method does not reduce.
      int firstProduct = lhs.numerator * rhs.denominator;
      int secondProduct = rhs.numerator * lhs.denominator;
      return new Fraction(
      firstProduct + secondProduct,
      lhs.denominator * rhs.denominator
      );
   }

   // return a string representation of the fraction
   public override string ToString(  )
   {
      String s = numerator.ToString(  ) + "/" +
      denominator.ToString(  );
      return s;
   }
}


public class Tester
{
   public void Run(  )
   {
      Fraction firstFraction = new Fraction( 3, 4 );
      Console.WriteLine( "firstFraction: {0}", firstFraction.ToString(  ) );

      Fraction secondFraction = new Fraction( 2, 4 );
      Console.WriteLine( "secondFraction: {0}", secondFraction.ToString(  ) );

      Fraction sumOfTwoFractions = firstFraction + secondFraction;
      Console.WriteLine(
         "firstFraction + secondFraction = sumOfTwoFractions: {0}",
         sumOfTwoFractions.ToString(  ) );

   }
   static void Main(  )
   {
      Tester t = new Tester(  );
      t.Run(  );
   }
}

The output looks like this:

    firstFraction: 3/4
    secondFraction: 2/4
    firstFraction + secondFraction = sumOfTwoFractions: 5/4

In Figure, you start by creating a Fraction class. The private member data is the numerator and denominator, stored as integers:

    public class Fraction
    {
     private int numerator;
     private int denominator;

The constructor just initializes these values. The overloaded addition operator takes two Fraction objects, returns a Fraction, and is marked static:

    public static Fraction operator+(Fraction lhs, Fraction rhs)
    {

If the denominators for the fractions are the same, you add the numerators and return a new Fraction object created by passing in the sum of the numerators as the new numerator and the shared denominator as the new denominator:

    if (lhs.denominator == rhs.denominator)
    {
         return new Fraction(lhs.numerator+rhs.numerator,
         lhs.denominator);
    }

The Fraction objects firstFraction and secondFraction are passed in to the overloaded addition operator as lhs and rhs, respectively. The new Fraction is created on the heap, and a reference is returned to the calling method, Run( ), where it is assigned to sumOfTwoFractions:

    Fraction sumOfTwoFractions = firstFraction + secondFraction;
    Console.WriteLine( "firstFraction + secondFraction = sumOfTwoFractions: {0}",
       sumOfTwoFractions.ToString(  ) );

Back in the implementation of the operator, if the denominators are different, you cross-multiply before adding. This allows you to add like Fractions.

        int firstProduct = lhs.numerator * rhs.denominator;
        int secondProduct = rhs.numerator * lhs.denominator;
        return new Fraction(
         firstProduct + secondProduct,
         lhs.denominator * rhs.denominator
     );

The two local variables, firstProduct and secondProduct, are temporary; they are destroyed when the method returns. The new Fraction created, however, is not temporary; it is created on the heap, and a reference is returned as previously.

A good Fraction class would, no doubt, implement all the arithmetic operators (addition, subtraction, multiplication, division). To overload the multiplication operator, you would write operator*; to overload the division operator, you would write operator/.


The Fraction class overrides the ToString( ) method (inherited from Object) to allow you to display the fractions by passing them to Console.WriteLine( ). (For more information about overloading methods, see Chapter 8.)



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows