ThinkGeek - Cool Stuff for Geeks and Technophiles

If you’ve used LINQ and lambdas, I’m sure you’ve come across the occasional function that requires an implementation of IEqualityComparer,or IComparer. You were hoping to write a little Lambda predicate but NOOOOOO, now you have to create a new type and implement an interface. Well no longer. I’m hoping these are the last two classes, in the history of mankind, that inherit from IComparer and IEqualityComparer:

public class Comparer<T> : IComparer<T>
{
   private Func<T, T, int> _compareFn;

   public Comparer(Func<T, T, int> fn)
   {
      _compareFn = fn;
   }

   public int Compare(T x, T y)
   {
      return _compareFn(x, y);
   }

}

public class EqualityComparer<T> : IEqualityComparer<T>
{
   private Func<T, T, bool> _equalsFn;
   private Func<T, int> _getHashCodefn;

   public EqualityComparer(Func<T, T, bool> equalsFn, Func<T, int> getHashCodefn)
   {
      _equalsFn = equalsFn;
      _getHashCodefn = getHashCodefn;
   }

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

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

2 Examples:

List<int> l = new List<int> { 1, 2, 5, 7, 999, 234, 4 };
l.Sort(new Comparer<int>((x, y) => x < y ? -1 : x == y ? 0 : 1));

Dictionary<int, string> d = new Dictionary<int, string>() { { 1, "a" }, { 2, "a" }, { 3, "b" } };

var d2 = d.Distinct(new EqualityComparer<KeyValuePair<int, string>>(
   (kvp1, kvp2) => kvp1.Value == kvp2.Value, kvp => kvp.Value.GetHashCode()));