Mar 18, 2007

Notes on C# operator overloading.

In any class, operators can be overloaded to give new meaning.

Example

public static RETURN_TYPE operator<OPERATOR> (...){...}

// integer addition
public static int operator+ (int left, int right){ return left+right;}

Example from Learning C# 3.0

public class Fraction 
{
    ...
    public static Fraction operator+ (Fraction left, Fraction right)
    {
        ...
        return new Fraction(...)
    }    

    public static Fraction operator+ (Fraction left, Fraction right){ return new Fraction(...)}
    public static Fraction operator* (Fraction left, Fraction right){ return new Fraction(...)}
    public static Fraction operator/ (Fraction left, Fraction right){ return new Fraction(...)}
    public static Fraction operator- (Fraction left, Fraction right){ return new Fraction(...)}
    
}

Comparison operators

==: equal operator

Example

public static bool operator ==(List a, List b) {
    return Equals(a, b);
}

Example

public class Employee 
{
    int id; // employee id #, assumed unique
    public static bool operator==(Employee left, Employee right)
    { return left.id==right.id ;}
    public static bool operator!=(Employee left, Employee right)
    { return !(left==right)}
}

For !=, use this, since == is already defined:

    { return !(left==right);}

Equals(): if == is overloaded, then it is recommended to implemenet Equals() as well. Assuming that == has been implemented, use this for most Equals in your class:

public override bool Equals(object o)
{
    if (!(o is Employee) ) return false;
    return this==(Employee)o;
}

’>’ , ‘<’ if one is implemented, both must be implemented Also, less than or equal and greater than or equal should also be implemented if above, if > and < are defined.

public static bool operator> (Fraction left, Fraction right){ return ...;} 
public static bool operator< (Fraction left, Fraction right){ return ...;}
public static bool operator<= (Fraction left, Fraction right){ return ...;}
public static bool operator>= (Fraction left, Fraction right){ return ...;}

Implicit vs Explicit

implicit: conversion is guaranteed to succeed. no casting.

int intVal=5;
long longVal = intVal;  // implicitly ok

explicit: otherwise. requires casting.

int intVal = 5L;  // ### ERROR!  cannot implicitly convert long to int 

int intVal = (int)5L;   // OK. Explicit conversion / casting

Ex

// Learning C# 3.0 - O'Reilly
// convert int to fraction. implicit 
public static implicit operator Fraction(int theInt)
{ return new Fraction(theInt);}

// convert fraction to int. explicit.
// bc value is truncated, i.e. 1/2 ==> 1 int
public static explicit operator int(Fraction theFraction)
{
    return theFraction.numerator / theFraction.denominator; 
}

//
myFraction = 5;  // implicit convert to 5/1.
myInt = (int)myFraction;  // explicit convert to 5, truncates