Tidy IEqualityComparer with GenericEqualityComparer

Whilst looking through a codebase, I saw implementations of IEqualityComparer<>. After thinking to myself that the need to create an entire implementation of IEqualityComparer<> per use creates quite a bit of boilerplate for such a small amount of signal, I realised that creating a generic implementation of IEqualityComparer<> that takes a definition of equality in its constructor would be very simple.

However, I was a bit embarrassed when I told my boss, Tony Beveridge, about this great use of generics and Funcs I had thought of, and he told me he had actually implemented exactly the same class some months ago.

Its worth noting that EqualityComparer<T>.Default provides a default implementation using the Equals() and GetHashCode() functions of T.

If you wanted to extend GenericEqualityComparer so you don’t have to provide an implementation for GetHashCode(), you can default mGetHashCodeFunc to always return zero. This will force the Equals function to always be called.

With a stronger guarantee for hash code, you could have one Func only. But the second sentence spoils it….(from MSDN):

“If two objects compare as equal, the GetHashCode method for each object must return the same value. However, if two objects do not compare as equal, the GetHashCode methods for the two object do not have to return different values.”

I meant Func(TSource, TKey), as is used by e.g. OrderBy and GroupBy. Your EqualityComparer itself would then be responsible for checking equality of the two “keys” (probably by delegating to EqualityComparer(TKey).Default). This key could then also be used for providing hashcodes, as I assume the hash algorithms for primitive “key-like” types are sound.

See also the implementations of DistinctBy in F# and Jon Skeet’s MoreLinq.