Mag*_*nus 2 c# search delegates
这听起来像是一个太容易被谷歌找到的问题,我想/希望我在试图实现我自己的版本时陷入细节.我要做的是根据我的Datatype对象对MyClass对象列表进行排序,应该使用不同的搜索功能.
对于类Datatype,我有类似的东西:
class Datatype {
public delegate int CMPFN(object x, object y);
private CMPFN compareFunction;
(...)
private XsdDatatype((...), CMPFN compareFunction) {
(...)
this.compareFunction = compareFunction;
}
public CMPFN GetCompareFunction() {
return this.compareFunction;
}
static private int SortStrings(object a, object b) {
return ((MyClass)a).GetValue().CompareTo(((MyClass)b).GetValue());
}
}
Run Code Online (Sandbox Code Playgroud)
后来我试图对MyClass列表进行排序:
List<MyClass> elements = GetElements();
Datatype datatype = new Datatype((...), Datatype.SortStrings);
elements.Sort(datatype.GetCompareFunction()); // <-- Compile error!
Run Code Online (Sandbox Code Playgroud)
我并不是对Datatype.SortStrings中的强制转换感到过于兴奋,但感觉这可能有效(?).然而,编译器不同意并在上面的最后一行给我这个错误,我有点不确定为什么CMPFN不能转换/转换(?)到IComparer.
Cannot convert type 'proj.Datatype.CMPFN' to 'System.Collections.Generic.IComparer<proj.MyClass>'
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 10
代表们不是那样的鸭子.您可以创建一个Comparison<MyClass>from,CMPFN但不能使用普通的引用转换 - 隐式或显式转换.
三种选择:
像这样创建比较器:
elements.Sort(new Comparison<MyClass>(datatype.GetCompareFunction()));
Run Code Online (Sandbox Code Playgroud)使用lambda表达式创建Comparison<T>并使用它代替:
elements.Sort((x, y) => datatype.GetCompareFunction()(x, y));
Run Code Online (Sandbox Code Playgroud)编写一个IComparer<MyClass>基于a执行比较的实现CMPFN
请注意,第二种方法将GetCompareFunction在每次比较时调用一次.
一个更好的解决方案是CMPFN完全摆脱- 为什么不只是使用(或实现)IComparer<MyClass>开始?请注意,这也将删除强制转换.(如果您对使用代理而不是接口感到满意,则可以将比较表示为Comparison<MyClass>代替.)
请注意,从.NET 4.5开始,您可以使用从委托Comparer.Create创建.Comparer<T>Comparison<T>
我不确定为什么你当前的API是这样的object,但你应该知道在C#3及更早版本(或C#4定位.NET 3.5及更早版本)中你将无法将其转换IComparer<object>为IComparer<MyClass>(通过参考转换,无论如何).从C#4开始,由于通用的逆转,你可以.