Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用IComparer<&燃气轮机;使用委托函数进行搜索_C#_Search_Delegates - Fatal编程技术网

C# 使用IComparer<&燃气轮机;使用委托函数进行搜索

C# 使用IComparer<&燃气轮机;使用委托函数进行搜索,c#,search,delegates,C#,Search,Delegates,这感觉像是一个很容易被谷歌发现的问题,我想/希望在尝试实现我自己的版本时,我已经被困在细节中了。我试图做的是根据我的数据类型对象对MyClass对象列表进行排序,应该使用不同的搜索函数 对于类数据类型,我想到了类似的东西: class Datatype { public delegate int CMPFN(object x, object y); private CMPFN compareFunction; (...) private XsdDatatype((...),

这感觉像是一个很容易被谷歌发现的问题,我想/希望在尝试实现我自己的版本时,我已经被困在细节中了。我试图做的是根据我的数据类型对象对MyClass对象列表进行排序,应该使用不同的搜索函数

对于类数据类型,我想到了类似的东西:

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函数。我知道当时没有,但因为这是一个流行的搜索结果。。。