This is what I came up with after reviewing Solution 1 by Tomas Takac
using System;
using System.Collections.Generic;
using System.Linq;
namespace Extensions.Linq
{
public static class FuncExtensions
{
public static IComparer<TElement> ToComparer<TElement,TKey>(this Func<telement,> func) where TKey : IComparable
{
return new ProjectionComparers<TElement,TKey>(func);
}
public static IComparer<TElement> ToComparer<TElement,TKey>(this IEnumerable<Func<TElement,TKey>> funcs) where TKey : IComparable
{
return new ProjectionComparers<TElement,TKey>(funcs.ToArray());
}
internal class ProjectionComparers<TElement,TKey> : IComparer<TElement> where TKey :IComparable
{
private readonly List<comparedelegate> _compareDelegates = new List<comparedelegate>();
private delegate int CompareDelegate(TElement x, TElement y);
internal ProjectionComparers(params Func<TElement,TKey>[] funcs)
{
foreach (var f in funcs)
{
var func = f;
_compareDelegates.Add(
(x, y) =>
{
TKey keyX = func(x);
TKey keyY = func(y);
return Comparer<TKey>.Default.Compare(keyX, keyY);
});
}
}
public int Compare(TElement x, TElement y)
{
return _compareDelegates
.Select(compareDelegate => compareDelegate(x, y))
.FirstOrDefault(result => result != 0);
}
}
}
}
Not yet tested so I'm sure I'll be tweaking this solution.
EDIT: removed the ctor with Comparers and insisted that TKey is comparable. The suits my case fine