This questions involves 2 different implementations of essentially the same code.
First, using delegate to create a Comparison method that can be used as a parameter whe
Probably the biggest advantage to accepting a Comparison as opposed to an IComparer is the ability to write anonymous methods. If I have, let's say, a List, where MyClass contains an ID property that should be used for sorting, I can write:
myList.Sort((c1, c2) => c1.ID.CompareTo(c2.ID));
Which is a lot more convenient than having to write an entire IComparer implementation.
I'm not sure that accepting an IComparer really has any major advantages, except for compatibility with legacy code (including .NET Framework classes). The Comparer property is only really useful for primitive types; everything else usually requires extra work to code against.
To avoid code duplication when I need to work with IComparer, one thing I usually do is create a generic comparer, like this:
public class AnonymousComparer : IComparer
{
private Comparison comparison;
public AnonymousComparer(Comparison comparison)
{
if (comparison == null)
throw new ArgumentNullException("comparison");
this.comparison = comparison;
}
public int Compare(T x, T y)
{
return comparison(x, y);
}
}
This allows writing code such as:
myList.BinarySearch(item,
new AnonymousComparer(x.ID.CompareTo(y.ID)));
It's not exactly pretty, but it saves some time.
Another useful class I have is this one:
public class PropertyComparer : IComparer
where TProp : IComparable
{
private Func func;
public PropertyComparer(Func func)
{
if (func == null)
throw new ArgumentNullException("func");
this.func = func;
}
public int Compare(T x, T y)
{
TProp px = func(x);
TProp py = func(y);
return px.CompareTo(py);
}
}
Which you can write code designed for IComparer as:
myList.BinarySearch(item, new PropertyComparer(c => c.ID));