Well apparently very difficult! Today, I read article after article on blogs that suggested weird and wonderful ways of overloading the operator == in C#. Almost all of those were incorrect! So I set myself a challenge to put the record straight:

Before showing you the code, a number of things to remember:

-          Overriding operator == is a feature of the C# language and there is no equivalent for it in the Intermediate Language (IL). In other words, the compiler replaces operator == with method calls to the operator overload’s static method.

-          Any type that overloads operator == should also overload operator !=

-          It only makes sense to override both Equals and GetHashCode methods when overloading operator ==.

-          Just to put the record straight, if the GetHashCode of two objects of the same type return the same value, it does NOT mean they are equal!

-          Also remember, if you are overloading operator ==, avoid using operator == in its implementation. You will probably get stock in an infinite recursion.

-          ReferenceEquals and cast to object should be your friends to avoid recursion and calls to unwanted methods (i.e. You probably don’t want to call operator == overload from the Equals method when evaluating something like obj == null)

-          You need to look after null values!

-          Use the static Object.Equals method in operator == and != overloads to avoid needing to overload  operator == for each inheritor of your class (The instance Equals method is virtual)

So here is an example:

class Rectangle

{

   private readonly int _x;

   private readonly int _y;

 

   public Rectangle(int x, int y)

   {

      _x = x;

      _y = y;

   }

 

   public override int GetHashCode()

   {

      return _x ^ _y;

   }

 

   public override bool Equals(object obj)

   {

      if (ReferenceEquals(obj, this))

         return true;

 

      Rectangle rect = obj as Rectangle;

 

      // need to use ReferenceEquals or cast rect to object

      // to avoid a call to the == operator overload below

      if (ReferenceEquals(rect, null))

         return false;

 

      return rect._x == _x && rect._y == _y;

   }

 

   public static bool operator ==

      (Rectangle r1, Rectangle r2)

   {

      // use Object.Equals to avoid needing to to provide == operator

      // overload for all inheritors of this class

      return Object.Equals(r1, r2);

   }

 

   public static bool operator !=

      (Rectangle r1, Rectangle r2)

   {

      return !Object.Equals(r1, r2);

   }

}