BlackWaspTM
C# Programming
.NET 1.1+

C# Relational Operator Overloading (2)

The eleventh article in the C# Object-Oriented Programming tutorial furthers the investigation of operator overloading. This time the overloading of the relational operators is described, allowing custom classes to be included in comparison operations.

Overloading Equality and Inequality Operators in the Vector Class

Using the syntax described above we can add overloaded equality and inequality operators to the Vector class. The operations will check that both the X and Y co-ordinates of the two Vectors being compared match before deeming the objects to be equal. To overload the two operators, add the following code to the Vector class:

public static bool operator ==(Vector v1, Vector v2)
{
    return (v1.X == v2.X && v1.Y == v2.Y);
}

public static bool operator !=(Vector v1, Vector v2)
{
    return (v1.X != v2.X || v1.Y != v2.Y);
}

These modifications change the comparisons so that the previous Main method's results are different. Execute the program again to see that the equality operator now compares the values in the Vector rather than the object references. Note that the v1 and v2 vectors are now considered equal.

static void Main(string[] args)
{
    Vector v1 = new Vector(3, 4);
    Vector v2 = new Vector(3, 4);
    Vector v3 = v2;

    Console.WriteLine(v2 == v1);                // Outputs "True"
    Console.WriteLine(v3 == v2);                // Outputs "True"
}

The Equals Method

Every class automatically inherits the Equals method. This method performs a comparison of two values or objects, returning a Boolean value indicating if the two items match. For reference type objects such as the Vector class, the comparison is of the two object references. Once the equality operator has been overloaded, the results of == and the Equals method are no longer the same:

static void Main(string[] args)
{
    Vector v1 = new Vector(3, 4);
    Vector v2 = new Vector(3, 4);
    Vector v3 = v2;

    Console.WriteLine(v2 == v1);                // Outputs "True"
    Console.WriteLine(v3 == v2);                // Outputs "True"
    Console.WriteLine(v2.Equals(v1));           // Outputs "False"
    Console.WriteLine(v3.Equals(v2));           // Outputs "True"
}

Generally you will want to modify the functionality of the Equals method to match that of the equality operator. This is achieved by overriding the method; a technique that will be described in a later article in this tutorial. After changing the Equals method, a test that the references for two objects match can still be made using the static ReferenceEquals method.

The GetHashCode Method

The GetHashCode method is another member that must be considered when overloading the equality operator for a class. This method uses a hashing algorithm to generate an integer hash code for an object. The hash code generated can be used for many purposes including within a Hashtable collection.

The default implementation for the GetHashCode method generates a hash code value that can be different for two functionally equivalent objects. As with the Equals method, it is usual that when overloading the equality operator you will want to override the GetHashCode method. The hash codes produced can then be based upon the value of the underlying object rather than the object reference.

NB: Warning messages are produced by the compiler when the equality operator is overloaded but the Equals and GetHashCode methods are not overridden. These warnings should not be ignored but will not prevent the code from being compiled or executed.

9 December 2007