使用IComparer <>和委托函数进行搜索

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但不能使用普通的引用转换 - 隐式或显式转换.

三种选择:

请注意,第二种方法将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开始,由于通用的逆转,你可以.

  • 从框架4.5开始,您可以使用Comparer <T> .Create函数来创建comaprison函数.我知道它当时不可用,但因为这是一个受欢迎的搜索结果...... (2认同)