Search code examples
c#equalsgethashcodeiequalitycomparer

How should I implement IEqualityComparer<T>.Equals


Concerning IEqualityComparer, is there ever a reason why the Equals(T x, T y) implementation should be anything other than what I have below?

public class MyEquality : IEqualityComparer<MyType>
{
    //My Equals(T x, T y) always looks like this
    public bool Equals(MyType x, MyType y)
    {
        return this.GetHashCode(x).Equals(this.GetHashCode(y));
    }

    public int GetHashCode(MyType obj)
    {
        //assume MyType has a non-nullable member called ID
        return obj.ID.GetHashCode();
    }
}

Solution

  • Yes. Hash codes can collide and in fact, they will with many types. They only exist to ensure equidistribution of values in hash tables, they are not useful for determining equality of values. Eric Lippert has also a take on this (and another one):

    It is a really bad idea to use 32 bit hash codes as “unique” identifiers. Hash values aren't random per se, but if they're well-distributed then they might as well be for our purposes. You might think “well, sure, obviously they are not truly unique since there are more than four billion possible values, but only four billion hash codes available. But there are so many possible hash values, odds are really good that I’m going to get unique values for my hashes”. But are the chances really that good? 9300 objects is not that many and 1% is a pretty high probability of collision.

    That being said, if your ID is the only thing you care for when determining equality, then comparing that ID should suffice. But not its hash code because a hash code only says

    a.GetHashCode() ≠ b.GetHashCode() → ab

    Note that nothing is said about the case where the hash code is the same.