Introduction
Inspired by the Q&A item Func<TElement, TKey1, TKey2> To IComparer<TElement>?", I came up with a generic fluent interface for a prioritized IComparer<T>. This tip publishes my solution for that Q&A above (well, it's basically a copy of it ;-)).
Using the Code
The ChainedComparer
implements the fluent interface. A fluent interface is implemented here as a "cascate of methods".
Example usage:
...
IComparer<MyRecordType> compareByYearAndMonth = ChainedComparer<MyRecordType>
.First(d => d.Year)
.Then (d => d.Month);
myContainer.Sort(compareByYearAndMonth);
...
Note: You can chain any number of .Then(...)
.
Implementation
The ChainedComparer
implementation is shown below:
public class ChainedComparer<TValue> : IComparer<TValue>
{
private List<Func<TValue, TValue, int>> _stages;
private ChainedComparer() { _stages = new List<Func<TValue,TValue,int>>(); }
public static ChainedComparer<TValue> First<TDimension>(Func<TValue, TDimension> selector)
where TDimension : IComparable<TDimension>
{
return new ChainedComparer<TValue>().Then(selector);
}
public ChainedComparer<TValue> Then<TDimension>(Func<TValue, TDimension> selector)
where TDimension : IComparable<TDimension>
{
_stages.Add((a, b) => selector(a).CompareTo(selector(b)));
return this;
}
public int Compare(TValue a, TValue b)
{
return _stages.Select(compare => compare(a, b)).FirstOrDefault(res => res != 0);
}
}
History
- 2015-06-18: Initial version