Search code examples
c#equalityiequatable

Why do two equal instances of IEquatable<T> return false?


Consider the following code

public class Rectangle : IEquatable<Rectangle>
{
    public int Width { get; set; }
    public int Height { get; set; }

    public bool Equals(Rectangle other)
    {
        return Width == other.Width
            && Height == other.Height;
    }
}

IEquatable<Rectangle> a = new Rectangle() { Width = 10, Height = 20 };
IEquatable<Rectangle> b = new Rectangle() { Width = 10, Height = 20 };

a.Equals(b); // returns false;

I know the value semantics of this class are awful (sorry). I normally follow the C# guidelines for IEquatable<T> implementation, which state that object.Equals(object obj) also needs to be overridden. - This is just speculation.

Since a and b are declared as IEquatable<Rectangle>, why when I call Equals, is it calling object.Equals(object obj), rather than IEquatable<Rectangle>.Equals(Rectangle other)?

It seems a little odd to use the object implementation over the IEquatable<T> implementation (again, I know I SHOULD override the classes default Equals(object obj) implementation...this is just speculation as to why this happens)


Solution

  • Consider the method:

    public bool Equals(Rectangle other)
    

    yet you're not passing it a Rectangle, you're passing it a IEquatable<Rectangle>, so the compiler won't choose that method. Instead it chooses the one inherited from System.Object which does basic reference comparison.

    Basically you have made the rectangle able to compare itself to another rectangle, then ask it to compare itself to something else that can compare itself to a rectangle. The compiler won't and can't infer that the only type this would apply to is a rectangle.