Thursday, October 12, 2017

Equality in C#

Ok, let's start with so-called reference equality (as in two pointers with same or different addresses).
In order to demonstrate reference comparison I'mma create some class and then instantiate it 2 times, so we cover both true and false cases:

class A{}

var a1 = new A();
var a2 = new A();


What's really interesting about this comparison is that its kinda default, meaning all method calls including equality operator will return true for a1 == a1:

var result1 = Object.Equals(a1,a1); // true
var result2 = Object.ReferenceEquals(a1, a1); // true
var result3 = a1.equals(a1); // true
var result4 = a1 == a2; // true

Correspondingly, all of them will return false for a1 == a2:

var result1 = Object.Equals(a1,a2); // false
var result2 = Object.ReferenceEquals(a1, a2); // false
var result3 = a1.equals(a2); // false
var result4 = a1 == a2; // false

Unlike Java C# actually has operator overloading, so why don't we overload all equality related methods of class A? Here is how we do this:

class A
{
    public static bool operator == (A a1, A a2)
    {
        return true;
    }

    // Irrelevant, but C# requires that we overload this one too
    public static bool operator != (A a1, A a2)
    {
         return false;
    }

    public bool Equals(A a)
    {
        return true;
    }
}

Let's compare a1 to a2 again:
var result1 = Object.Equals(a1,a2); // false
var result2 = Object.ReferenceEquals(a1, a2); // false
var result3 = a1.equals(a2); // true
var result4 = a1 == a2; // true

Now that we overloaded A's equality operators we can no longer rely on them to do reference equality comparison unless we know for sure they behave exactly like the default ones. In other words if we want reference equality our best option is definitely Object.ReferenceEquals method.

Looks like I completely omitted Value Equality. Well, if you need it, just implement your own equality/inequality operators and Equals method.


No comments:

Post a Comment