2

我有一个函数我想写一个返回排序列表的地方。我想传递对象的自定义比较。下面的例子相当简单,但如果我能克服这个问题,我应该做好准备。

我尝试过声明正确类型的委托(我认为):

public delegate int ObjectSorter(MyObject x, MyObject y);

用正确的语法调用它:

GetList(delegate(MyObject a, MyObject b) { return a.CompareTo(b); });

但是当我将它传递给列表时,我发现存在参数问题:

public List<MyObject> GetList(ObjectSorter os)
{
    List<MyObject> objectList = FillTheList();
    objectList.Sort(os);    // Invalid
    return ObjectList;
}

所以尝试不同的方法:

GetList((x, y) => { return x.CompareTo(y); });


public List<MyObject> GetList(Func<MyObject, MyObject, int> sorter)
{
    List<MyObject> objectList = FillTheList();
    objectList.Sort(sorter);    // Invalid also

    // This syntax DOES work, but too specific.  And why does it work?
    nl.Sort((x, y) => x.CompareTo(y));  

    return ObjectList;
}

也不行。

我试图让调用者尽可能轻松地对函数进行自定义比较,并让函数尽可能少地了解排序本身的工作原理。我宁愿不让调用者经历创建从 IComparer 派生的类并将其传入的所有麻烦。

4

2 回答 2

3

应该:

objectList.Sort(new Comparison<MyObject>(sorter));

或者只是将您的方法签名更改为:

public List<MyObject> GetList(Comparison<MyObject> sorter)

Comparison<MyObject>相当于你的Func<MyObject, MyObject, int> sorter.

nl.Sort((x, y) => x.CompareTo(y));工作,因为编译器自动变成(x, y) => x.CompareTo(y)一个Comparison<MyObject>委托。当您拥有代码(x, y) => x.CompareTo(y)时,编译器使用上下文来确定其类型。

一旦它被存储为特定的委托类型(例如Func<MyObject, MyObject, int>or Comparison<MyObject>),这就是它的类型,并且它不会隐式转换为另一个。但是,如果它兼容,它可以显式转换为另一种类型,如new Comparison<MyObject>(sorter).

于 2013-04-22T14:21:37.380 回答
1

您可以使用Func传入一个函数,例如:

private void Foo(Func<MyObject, MyObject, int> sortMethod)
{
   list.Sort(new Comparison<MyObject>(sortMethod));
}

示例排序方法:

public static int SortBytName(MyObject x, MyObject y)
{
    return x.Name.CompareTo(y.Name);
}
于 2013-04-22T14:22:18.997 回答