2013-05-30 27 views
45

C#在方法调用中是否可以使用lambda表达式作为IComparer参数?使用lambda表达式代替IComparer参数

例如像

var x = someIEnumerable.OrderBy(aClass e => e.someProperty, 
(aClass x, aClass y) => 
    x.someProperty > y.SomeProperty ? 1 : x.someProperty < y.SomeProperty ? -1 : 0); 

我不能完全得到这个编译所以我猜没有,但它似乎lambda表达式和匿名委托,我觉得我必须做一些之间的这种明显的协同作用愚蠢的错误。

TIA

+1

可能的答案在这里:http://stackoverflow.com/questions/9824435/interface-implementing-anonymous-class-in-c –

回答

37

由于叶普指出,如果你在.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); 
    } 
} 
+0

可能要给这个班级一个不同的名称,以避免与图书馆的类冲突 – Servy

+0

@Servy好点 - 改变 –

+0

句法细节:泛型类的构造函数不能包含类名称的''部分 –

50

如果你在.NET 4.5中,可以使用静态方法Comparer<aClass>.Create

文档:Comparer<T>.Create Method

例子:

var x = someIEnumerable.OrderBy(e => e.someProperty, 
    Comparer<aClass>.Create((x, y) => x.someProperty > y.SomeProperty ? 1 : x.someProperty < y.SomeProperty ? -1 : 0) 
    ); 
+0

可悲的是,我们在.net 3.5陆地!无法承受将TFS升级到最新版本所需的巨型楔子:-( – haughtonomous

+2

@如果这是唯一让你失望的事情,你有没有考虑将TFS倾倒到其他东西上? –

3

如果你一直想比较突出键(如单个属性),你可以定义封装了所有关键的比较级逻辑你,包括null检查,在这两个对象密钥提取,和键比较使用指定或默认的内部比较器:

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)); 

你可以参考我的blog post该实现的扩展讨论。