Search code examples
c#recordequalityequals-operator

Override Equals method on records


Consider this Minimal Reproducible Example.

Point point1 = new Point(1, 2, 3);
Point point2 = new Point(1, 2, 31);

Console.WriteLine(point1 == point2);  // True
Console.WriteLine(point1.Equals(point2));  // True

record Point(double X, double Y, double Z)
{
    public virtual bool Equals(Point other)
    {
        return other != null && X == other.X && Y == other.Y;
    }
}

Do I override the == method with Equals? It seems I do too (and I don't only override .Equals). Is there a way to only override one of them?


Solution

  • With record types, there is no difference between value equality (tested with Equals) and reference equality (tested with ==). To quote the documentation:

    The same methods and operators that indicate reference equality or inequality in classes (such as Object.Equals(Object) and ==), indicate value equality or inequality in records.

    I.e., by overriding the Equals method, you're also changing the behavior of ==, as expected for records.

    A sort of partial workaround would be to add your own method for logical equality and not override Equals. This will allow you to test this logic without changing the behavior of ==, but of course it's a very partial solution - it won't allow you to use this logic in other classes that expect Equals to be overridden (such as sets or dictionaries):

    // Not overriding Equals
    public virtual bool LogicallyEquals(Point other)
    {
        return other != null && X == other.X && Y == other.Y;
    }