C# == vs Equals
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