Search code examples
.netlinqdelegates

Wrap a delegate in an IEqualityComparer


Several Linq.Enumerable functions take an IEqualityComparer<T>. Is there a convenient wrapper class that adapts a delegate(T,T)=>bool to implement IEqualityComparer<T>? It's easy enough to write one (if your ignore problems with defining a correct hashcode), but I'd like to know if there is an out-of-the-box solution.

Specifically, I want to do set operations on Dictionarys, using only the Keys to define membership (while retaining the values according to different rules).


Solution

  • Ordinarily, I'd get this resolved by commenting @Sam on the answer (I've done some editing on the original post to clean it up a bit without altering the behavior.)

    The following is my riff of @Sam's answer, with a [IMNSHO] critical fix to the default hashing policy:-

    class FuncEqualityComparer<T> : IEqualityComparer<T>
    {
        readonly Func<T, T, bool> _comparer;
        readonly Func<T, int> _hash;
    
        public FuncEqualityComparer( Func<T, T, bool> comparer )
            : this( comparer, t => 0 ) // NB Cannot assume anything about how e.g., t.GetHashCode() interacts with the comparer's behavior
        {
        }
    
        public FuncEqualityComparer( Func<T, T, bool> comparer, Func<T, int> hash )
        {
            _comparer = comparer;
            _hash = hash;
        }
    
        public bool Equals( T x, T y )
        {
            return _comparer( x, y );
        }
    
        public int GetHashCode( T obj )
        {
            return _hash( obj );
        }
    }