Generic IEqualityComparer<T> and GetHashCode

mathieu picture mathieu · May 6, 2011 · Viewed 8.2k times · Source

Being somewhat lazy about implementing lots of IEqualityComparers, and given that I couldn't easily edit class implementations of object being compared, I went with the following, meant to be used with Distinct() and Except() extension methods. :

public class GenericEqualityComparer<T> : IEqualityComparer<T>
{
    Func<T, T, bool> compareFunction;
    Func<T, int> hashFunction;

    public GenericEqualityComparer(Func<T, T, bool> compareFunction, Func<T, int> hashFunction)
    {
        this.compareFunction = compareFunction;
        this.hashFunction = hashFunction;
    }

    public bool Equals(T x, T y)
    {
        return compareFunction(x, y);
    }

    public int GetHashCode(T obj)
    {
        return hashFunction(obj);
    }
}

Seems nice, but is giving an hash function everytimes REALLY necessary ? I understand that the hashcode is used to put objects in buckets. Different buckets, object are not equal, and equal is not called.

If GetHashCode returns the same value, equals is called. ( from : Why is it important to override GetHashCode when Equals method is overridden? )

So what could go wrong, if for example (and I hear a lot of programmers screaming in horror), GetHashCode returns a constant, to force the call to Equal ?

Answer

spender picture spender · May 6, 2011

Nothing would go wrong, but in hash-table based containers, you're going from approx O(1) to O(n) performance when doing a lookup. You'd be better off simply storing everything in a List and brute force searching it for items that fulfil equality.