C# 使用IComparer<&燃气轮机;使用委托函数进行搜索
这感觉像是一个很容易被谷歌发现的问题,我想/希望在尝试实现我自己的版本时,我已经被困在细节中了。我试图做的是根据我的数据类型对象对MyClass对象列表进行排序,应该使用不同的搜索函数 对于类数据类型,我想到了类似的东西:C# 使用IComparer<&燃气轮机;使用委托函数进行搜索,c#,search,delegates,C#,Search,Delegates,这感觉像是一个很容易被谷歌发现的问题,我想/希望在尝试实现我自己的版本时,我已经被困在细节中了。我试图做的是根据我的数据类型对象对MyClass对象列表进行排序,应该使用不同的搜索函数 对于类数据类型,我想到了类似的东西: class Datatype { public delegate int CMPFN(object x, object y); private CMPFN compareFunction; (...) private XsdDatatype((...),
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!
elements.Sort(new Comparison<MyClass>(datatype.GetCompareFunction()));
List elements=GetElements();
Datatype Datatype=新数据类型((…),Datatype.SortString);
elements.Sort(datatype.GetCompareFunction());// 代理不是那种鸭子式的。您可以从CMPFN
创建比较
,但不能使用普通引用转换(隐式或显式)
三种选择:
- 按如下方式创建比较器:
List<MyClass> elements = GetElements();
Datatype datatype = new Datatype((...), Datatype.SortStrings);
elements.Sort(datatype.GetCompareFunction()); // <-- Compile error!
elements.Sort(new Comparison<MyClass>(datatype.GetCompareFunction()));
- 编写一个
IComparer
的实现,该实现基于CMPFN
请注意,第二种方法将在每次比较时调用GetCompareFunction
一个更好的解决方案是完全摆脱CMPFN
——为什么不首先使用(或实现)IComparer
?请注意,这也会删除类型转换。(如果您喜欢使用委托而不是接口,则可以将比较表示为比较
)
请注意,从.NET 4.5开始,您可以使用从比较
委托创建比较器
我不知道为什么您当前的API是在对象方面,但您应该知道,在C#3及更早版本(或C#4以.NET 3.5及更早版本为目标)中,您将无法将IComparer
转换为IComparer
(无论如何,通过引用转换)。从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());
类属性报告:IComparer
{
#地区I比较成员
公共整数比较(属性类x、属性类y)
{
如果(x==null | | y==null)
抛出新ArgumentException(“至少有一个参数为null”);
如果(x.attributeNo==y.attributeNo)返回0;
如果(x.attributeNo
你可以这样称呼它
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());
列出带有OBJ的列表。。。。
listWithObj.Sort(新的AttributeSort());
应该像你想的那样工作。您还可以创建类型安全比较器类。列表.Sort有许多重载,但没有一个重载使用您定义的参数(两个对象)接受委托
但是,有一个重载需要委托,您只需对代码进行一些小的修改就可以使用委托。基本上,您只需将您的CMPFN
委托替换为比较
——作为额外的奖励,您还可以在排序字符串
函数中进行强键入:
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());
静态私有int-SortStrings(MyClass a,MyClass b){
返回a.GetValue().CompareTo(b.GetValue());
}
公共比较GetCompareFunction(){
返回SortString;//或其他内容
}
...
elements.Sort(datatype.GetCompareFunction());
为什么缺少泛型?OP显然在原始代码中使用了泛型,因此我看不到任何返回ArrayList
和非泛型IComparer
界面的调用。我的错,时间还早,代码已经完成(可能是旧的)但它的通用版本到目前为止没有太大的不同。。。。当然你不能new
一个icomparaer
?@Richard:我的错。我的头一直在我的土地上。将编辑。这显然太早了:)我想知道,如果,正如它应该有的那样…@Richard:为了获得额外的LOL,你可以新建一个界面。。。如果是COM接口。这非常奇怪:)从Framework4.5开始,您可以使用Comparer.Create函数来创建comaprison函数。我知道当时没有,但因为这是一个流行的搜索结果。。。