19

匿名函数如何作为方法的参数而不是构造函数参数?


如果我创建一个List<string>,它有一个带有以下签名的 Sort 方法:

public void Sort(IComparer<T> comparer)

以下工作:

List<string> list = new List<string>();
list.Sort( (a,b) => a.CompareTo(b) );

SortedSet 有一个具有类似签名的构造函数:

public SortedSet(IComparer<T> comparer)

但是在构造函数中使用匿名函数时会失败。以下内容无效:

SortedSet<string> set = new SortedSet<string>( (a, b) => a.CompareTo(b) );

创建一个排序类可以按预期工作:

public class MyComparer : IComparer<string>
{
    public int Compare(string a, string b)
    { return a.CompareTo(b); }
}

SortedSet<string> set = new SortedSet<string>( new MyComparer() );
4

4 回答 4

32

那是因为构造函数接受一个IComparer<T>(接口),而不是一个Comparison<T>(委托)。Anon-methods / lambdas 可以支持委托,但不能(直接)支持接口。不过,它很容易包装 - 例如:

class FuncComparer<T> : IComparer<T>
{
    private readonly Comparison<T> comparison;
    public FuncComparer(Comparison<T> comparison) {
        this.comparison = comparison;
    }
    public int Compare(T x, T y) {
        return comparison(x, y); }
}

现在您可以使用:

SortedSet<string> set = new SortedSet<string>(
      new FuncComparer<string>( (a, b) => a.CompareTo(b) ));
于 2010-06-28T08:23:50.617 回答
32

.NET Framework 4.5 版本引入了工厂方法Comparer<T>.Create

var set = new SortedSet<string>(
    Comparer<string>.Create((a, b) => a.CompareTo(b)));
于 2014-04-21T20:31:26.883 回答
4

SortedSet 接受接口但不接受委托的解释很好。(但 Java 接受)。

正因为如此,.Net 人提供了一个工厂方法来创建这样一个对象,所以你不需要为此定义一个新类。

var set = new SortedSet<string>( 
    Comparer<string>.Create((a, b) => a.CompareTo(b))
);
于 2017-08-09T19:29:11.137 回答
0

我你的情况 List.Sort 使用这个签名

public void Sort(Comparison<T> comparison)

但不是这个

public void Sort(IComparer<T> comparer)
于 2010-06-28T08:27:13.477 回答