Search code examples
c#linqhashcodecomparable

Using GetHashCode of IEqualityComparer the right way


When using IEqualityComparer to compare objects in a collection, I'm not sure which one of the followings approaches is the best one.

Here is the implementation :

class CarComparer : IEqualityComparer<Car>
{
    public bool Equals(Car x, Car y)
    {
        throw new NotImplementedException();
    }

    public int GetHashCode(Car car)
    {
        //
    }
}

And here are my two options for GetHashCode implementation

    public int GetHashCode(Car row)
    {
        return HashCode.Combine(row.Name, row.Color , row.Size);
    }

Or,

    public int GetHashCode(Car row)
    {
        return row.GetHashCode();
    }

I don't like the first one because it make code less maintainable and probably less expensive in terms of resources. But a lot of people use it like that.

I would like to use my CarComparer in linq functions later. Like this:

cars.Distinct(new CarComparer());

Which one should I use?

Is this an opinion based question?


Solution

  • The correct answer:

    When using LINQ the GetHashCode is called before the Equals method and only when the result of the GetHashCode is equal for two items in the collection.

    So GetHashCode must be override too :

      public int GetHashCode(Car row)
    {
        return HashCode.Combine(row.Name, row.Color , row.Size);
    }
    

    See full response here