使用传入函数</t>对List <t>进行排序

时间:2013-04-22 14:17:20

标签: c# sorting delegates lambda

我有一个函数我想写一个返回排序列表的函数。我想传递对象的自定义比较。以下示例相当简单,但如果我能够解决这个问题,我应该设置好。

我已经尝试声明一个正确类型的代表(我认为):

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派生的类并将其传入的所有麻烦。

2 个答案:

答案 0 :(得分: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>Comparison<MyObject>),这就是它的类型,并且不会隐式转换为另一个。但是,如果它是兼容的,它可以显式转换为另一种类型,如new Comparison<MyObject>(sorter)

答案 1 :(得分: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);
}