我有一个函数我想写一个返回排序列表的函数。我想传递对象的自定义比较。以下示例相当简单,但如果我能够解决这个问题,我应该设置好。
我已经尝试声明一个正确类型的代表(我认为):
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派生的类并将其传入的所有麻烦。
答案 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);
}