使用lambdaexpression式代替IComparer参数
在C#中,是否可以在方法调用中将一个lambdaexpression式作为IComparerparameter passing?
例如类似的东西
var x = someIEnumerable.OrderBy(aClass e => e.someProperty, (aClass x, aClass y) => { return x.someProperty > y.SomeProperty ? 1 : x.someProperty < y.SomeProperty ? -1 : 0; } );
我不能完全得到这个编译,所以我不猜测,但似乎lambda和匿名代表之间的这种明显的协同作用,我觉得我必须做一些愚蠢的错误。
TIA
正如Jeppe指出的,如果你使用.NET 4.5,你可以使用静态方法Comparer<T>.Create
。
如果不是,这是一个应该是等价的实现:
public class FunctionalComparer<T> : IComparer<T> { private Func<T, T, int> comparer; public FunctionalComparer(Func<T, T, int> comparer) { this.comparer = comparer; } public static IComparer<T> Create(Func<T, T, int> comparer) { return new FunctionalComparer<T>(comparer); } public int Compare(T x, T y) { return comparer(x, y); } }
如果您使用的是.NET 4.5,则可以使用静态方法Comparer<aClass>.Create
。
文档: Comparer<T>.Create
方法 。
例:
var x = someIEnumerable.OrderBy(e => e.someProperty, Comparer<aClass>.Create((x, y) => x.someProperty > y.SomeProperty ? 1 : x.someProperty < y.SomeProperty ? -1 : 0) );
如果您一直想要比较计划的键(如单个属性),则可以定义一个类,为您封装所有键比较逻辑,包括空值检查,两个对象上的键提取以及使用指定或默认内部键比较比较器:
public class KeyComparer<TSource, TKey> : Comparer<TSource> { private readonly Func<TSource, TKey> _keySelector; private readonly IComparer<TKey> _innerComparer; public KeyComparer( Func<TSource, TKey> keySelector, IComparer<TKey> innerComparer = null) { _keySelector = keySelector; _innerComparer = innerComparer ?? Comparer<TKey>.Default; } public override int Compare(TSource x, TSource y) { if (object.ReferenceEquals(x, y)) return 0; if (x == null) return -1; if (y == null) return 1; TKey xKey = _keySelector(x); TKey yKey = _keySelector(y); return _innerComparer.Compare(xKey, yKey); } }
为了方便,工厂方法:
public static class KeyComparer { public static KeyComparer<TSource, TKey> Create<TSource, TKey>( Func<TSource, TKey> keySelector, IComparer<TKey> innerComparer = null) { return new KeyComparer<TSource, TKey>(keySelector, innerComparer); } }
你可以这样使用它:
var sortedSet = new SortedSet<MyClass>(KeyComparer.Create((MyClass o) => o.MyProperty));
你可以参考我的博客文章 ,对这个实现进行扩展讨论。