[英]Sorting an ArrayList by using IComparer Compare Function C#
[英]Using IComparer<> with delegate function to search
这听起来像是一个太容易被谷歌找到的问题,我想/希望我在试图实现我自己的版本时陷入细节。 我要做的是根据我的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());
}
}
后来我试图对MyClass列表进行排序:
List<MyClass> elements = GetElements();
Datatype datatype = new Datatype((...), Datatype.SortStrings);
elements.Sort(datatype.GetCompareFunction()); // <-- Compile error!
我并不是对Datatype.SortStrings中的强制转换感到过于兴奋,但感觉这可能有效(?)。 然而,编译器不同意并在上面的最后一行给我这个错误,我有点不确定为什么CMPFN不能转换/转换(?)到IComparer。
Cannot convert type 'proj.Datatype.CMPFN' to 'System.Collections.Generic.IComparer<proj.MyClass>'
代表们不是那样的鸭子。 您可以从CMPFN
创建 Comparison<MyClass>
,但不能使用简单引用转换 - 隐式或显式转换。
三种选择:
像这样创建比较器:
elements.Sort(new Comparison<MyClass>(datatype.GetCompareFunction()));
使用lambda表达式创建Comparison<T>
并使用它代替:
elements.Sort((x, y) => datatype.GetCompareFunction()(x, y));
编写IComparer<MyClass>
的实现,它基于CMPFN
执行比较
请注意,第二种方法将在每次比较时调用GetCompareFunction
一次。
一个更好的解决方案是完全摆脱CMPFN
- 为什么不直接使用(或实现) IComparer<MyClass>
? 请注意,这也将删除强制转换。 (如果您对使用委托而不是接口感到满意,则可以将比较表示为Comparison<MyClass>
。)
请注意,从.NET 4.5开始,您可以使用Comparer.Create
从Comparison<T>
委托创建Comparer<T>
。
我不确定为什么你当前的API是关于object
,但你应该知道在C#3及更早版本(或针对.NET 3.5及更早版本的C#4)中你将无法转换IComparer<object>
到IComparer<MyClass>
(通过引用转换,无论如何)。 从C#4开始,由于通用的逆转,你可以。
尝试这样的事情
class AttributeSort : IComparer<AttributeClass >
{
#region IComparer Members
public int Compare(AttributeClass x, AttributeClass y)
{
if (x == null || y == null)
throw new ArgumentException("At least one argument is null");
if (x.attributeNo == y.attributeNo) return 0;
if (x.attributeNo < y.attributeNo) return -1;
return 1;
}
#endregion
}
你可以像这样打电话给它
List<AttributeClass> listWithObj ....
listWithObj.Sort(new AttributeSort());
应该像你想要的那样工作。 您也可以创建一个类型安全的比较器类。
List<T>.Sort
存在许多重载,但是没有任何重载采用您定义的参数(两个对象)。
但是,有一个重载需要一个Comparison <T>委托,您可以通过一些小的修改来处理代码。 基本上,你只需用Comparison<MyClass>
替换你的CMPFN
代表 - 作为一个额外的好处,你也可以在SortStrings
函数中输入强类型:
static private int SortStrings(MyClass a, MyClass b) {
return a.GetValue().CompareTo(b.GetValue());
}
public Comparison<MyClass> GetCompareFunction() {
return SortStrings; // or whatever
}
...
elements.Sort(datatype.GetCompareFunction());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.