Wednesday, April 29, 2009

Converting Comparison<T> to IComparer<T>

IComparerToday, I was working with IComparers (mostly for my Demystifying IComparers blog post). I realized that there's a lot of use for IComparers when working with C# and Linq. I decided that I should dedicate an entire IComparer section to C# Icomparers.

I was working on fodder for several articles when I came across a little annoyance. There's not a Comparer class that takes a Comparison delegate as a constructor argument. Thus, I can call List.Sort() and pass a Comparison delegate or a lambda expression but I cannot create an IComparer that executes that delegate or lambda.

Dissatisfied with this state of affairs, I throw together this little class:
public class ComparisonComparer<T> : IComparer<T>
{
private readonly Comparison<T> _comparison;

public ComparisonComparer(Comparison<T> comparison)
{
_comparison = comparison;
}

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

4 comments:

  1. This is nice, but I prefer doing comparisons Python-style.

    In Python, when you call something like sort() or set() that requires you to pass a representation of "order" or "equality", instead of representing the it as a function that compares two elements, you pass a key function that takes ONE object and returns a value that is going to be compared/equated naturally.

    This may be less powerful but tends to cover my cases so far.

    I've made a handy implementation for C#: http://pastebin.com/wHpKuxiS

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Now (in 2012) there's a new version 4.5 of the .NET Framework, and it includes a static method Comparer<T>.Create which makes you create an IComparer<T> instance from a delegate (lambda) directly.

    ReplyDelete
  4. Thank you for this usefull little trick.

    ReplyDelete