C# == vs Equals

in #programming7 years ago

These two quality operations are not the same, so what is the difference?

This is a subtle one and most of the time these two operators behave in exactly the same way. Take the following value types comparison where == and Equals() give the same results:

var a = 5;
var b = 5;
var c = 6;


var result1 = a == b; // This is true
var result2 = a.Equals(b); // This is true
var result3 = a == c; // This is false
var result4 = a.Equals(c); // This is false

Now we move onto reference types, this is where things get more interesting.

public sealed class Point 
{
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public int X {get;}
    public int Y {get;}
}

var a = new Point(1, 2);
var b = new Point(1, 2);
var c = new Point(3, 8);

var result1 = a == a; // This is true
var result2 = a.Equals(a); // This is true
var result3 = a == b; // This is false
var result4 = a.Equals(b); // This is false
var result5 = a == c; // This is false
var result6 = a.Equals(c); // This is false

With reference type semantics the default for both comparisons is ReferenceEquals, but we can change that and provide value equality for our object.

public sealed class Point 
{
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public int X {get;}
    public int Y {get;}
    
    public override bool Equals(Object otherObj) 
    {
        var otherPoint = otherObj as Point;
        if (otherPoint == null) 
        {
            return false;
        }

        return (X == otherPoint.X) && (Y == otherPoint.Y);
    }

    public override int GetHashCode() 
    {
        return X ^ Y;
    }
}

var a = new Point(1, 2);
var b = new Point(1, 2);
var c = new Point(3, 8);

var result1 = a == a; // This is true
var result2 = a.Equals(a); // This is true
var result3 = a == b; // This is false
var result4 = a.Equals(b); // This is true
var result5 = a == c; // This is false
var result6 = a.Equals(c); // This is false

With reference types == compares reference equality while our Equals has been overloaded to value equality. You could also overload the == operator to provide value equality.

Overloading the == operator does come with a nice gotcha though, it is not polymorphic. A good example of this is strings, which are reference types with == overloaded to provide value equality.

var a = "Some text";
var b = "Some text";
var c = "Some other text";
object d = a;

var result1 = a == b; // This is true
var result2 = a == c; // This is false
var result3 = d == b; // This is false

In this example you see how overloading == can trip you up. Because we are using an object reference to a string the operator is not found so falls backs to reference equality. 'd' and 'b' do not reference the same object.

Feel free to ask any questions. Happy coding :)

Woz