Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.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# 比较器中的方法分辨率_C#_Overloading_Derived - Fatal编程技术网

C# 比较器中的方法分辨率

C# 比较器中的方法分辨率,c#,overloading,derived,C#,Overloading,Derived,考虑以下基本类布局: public class Base : IComparable<Base> { public int CompareTo(Base other) { //Do comparison } } public class Derived : Base, IComparable<Derived> { public int CompareTo(Derived other) { //Do comparison } }

考虑以下基本类布局:

public class Base : IComparable<Base>
{
  public int CompareTo(Base other)
  {
    //Do comparison
  }
}

public class Derived : Base, IComparable<Derived>
{
  public int CompareTo(Derived other)
  {
    //Do comparison
  }  
}

public class BaseComparer : IComparer<Base>
{
  public int Compare(Base x, Base y)
  {
   return x.CompareTo(y);
  }
}
公共类基:IComparable
{
公共整数比较(基本其他)
{
//做比较
}
}
派生的公共类:基类,IComparable
{
公共整数比较(派生其他)
{
//做比较
}  
}
公共类基比较器:IComparer
{
公共整数比较(基数x,基数y)
{
返回x.CompareTo(y);
}
}
然后使用以下各项:

List<Base> thingies = new List<Base>
{
  new Base(),
  new Derived(),
  new Derived()
};

thingies.Sort(new BaseComparer());
List thingies=新列表
{
新基(),
新的派生(),
新派生()
};
Sort(newbasecomparer());
在x和y参数都是派生实例的情况下,我希望比较器调用Derived.CompareTo方法

然而,情况并非如此,而是调用Base.CompareTo,我一直在想为什么。根据我对C语言规范中描述的重载解析规则的基本理解,我似乎无法推断这种行为


有人能帮我解释一下吗?

Base
不知道它的派生类,所以在
Base
中只有一个
CompareTo
方法,它被无条件调用

关键是重载解析发生在编译时,在编译时没有关于
Base
引用的实际类型的信息。您需要重写
派生的
中的方法,而不是重载它:

并另外标记
基。与
方法
虚拟
进行比较


请注意,这不再实现
IComparable
。您也可以这样做,但出于您的目的,这是不相关的。

Base
对其派生类一无所知–因此在
Base
中只有一个
CompareTo
方法,该方法将无条件调用

关键是重载解析发生在编译时,在编译时没有关于
Base
引用的实际类型的信息。您需要重写
派生的
中的方法,而不是重载它:

并另外标记
基。与
方法
虚拟
进行比较


请注意,这不再实现
IComparable
。您也可以这样做,但出于您的目的,这是不相关的。

这里发生的不是过载解决。您有两个独立的方法:它们的全名是
IComparable.CompareTo
IComparable.CompareTo

BaseComparer
唯一知道如何调用的是
IComparable.CompareTo
。它对
i可比性
一无所知

在您的应用程序中,将
Base
派生的
进行比较有意义吗?也就是说,可以说
Base
位于
派生的
之前或之后

  • 如果是这样,您最好只使用
    IComparable
    ,甚至使用非泛型的
    IComparable
    ,并准备检查子类中的类型
  • 如果不,则应考虑制作 Base<代码> >,只在叶类上执行<代码>可比较的< /代码> >
      这里发生的不是过载解决。您有两个独立的方法:它们的全名是
      IComparable.CompareTo
      IComparable.CompareTo

      BaseComparer
      唯一知道如何调用的是
      IComparable.CompareTo
      。它对
      i可比性
      一无所知

      在您的应用程序中,将
      Base
      派生的
      进行比较有意义吗?也就是说,可以说
      Base
      位于
      派生的
      之前或之后

      • 如果是这样,您最好只使用
        IComparable
        ,甚至使用非泛型的
        IComparable
        ,并准备检查子类中的类型
      • 如果不,则应考虑制作 Base<代码> >,只在叶类上执行<代码>可比较的< /代码> >
      IComparable
      IComparable
      是两种不同的类型,因此
      派生的
      中的两种方法
      比较
      映射到两个不同的插槽上
      CompareTo
      BaseComparer
      调用
      IComparable
      的方法调用。您可以将
      Base
      中的
      CompareTo(Base)
      表示为
      virtual
      ,并在
      Derived
      中重写它以获得(部分)预期行为

      public class Base : IComparable<Base>
      {
          public virtual int CompareTo(Base other)
          {
              // do comparison
          }
      }
      
      public class Derived : Base, IComparable<Derived>
      {
          public int CompareTo(Derived other)
          {
              // do comparison
          }
      
          public override int CompareTo(Base other)
          {
              if (other is Derived)
                  return CompareTo((Derived) other);
              return base.CompareTo(other);
          }
      }
      
      公共类基:IComparable
      {
      公共虚拟整数比较(基本其他)
      {
      //做比较
      }
      }
      派生的公共类:基类,IComparable
      {
      公共整数比较(派生其他)
      {
      //做比较
      }
      公共覆盖整数比较(基本其他)
      {
      如果(其他是派生的)
      返回CompareTo((派生)其他);
      返回基数。比较(其他);
      }
      }
      
      IComparable
      IComparable
      是两种不同的类型,因此
      派生的
      中的两种方法
      比较
      映射到两个不同的插槽
      CompareTo
      BaseComparer
      调用
      IComparable
      的方法调用。您可以将
      Base
      中的
      CompareTo(Base)
      表示为
      virtual
      ,并在
      Derived
      中重写它以获得(部分)预期行为

      public class Base : IComparable<Base>
      {
          public virtual int CompareTo(Base other)
          {
              // do comparison
          }
      }
      
      public class Derived : Base, IComparable<Derived>
      {
          public int CompareTo(Derived other)
          {
              // do comparison
          }
      
          public override int CompareTo(Base other)
          {
              if (other is Derived)
                  return CompareTo((Derived) other);
              return base.CompareTo(other);
          }
      }
      
      公共类基:IComparable
      {
      公共虚拟整数比较(基本其他)
      {
      //做比较
      }
      }
      派生的公共类:基类,IComparable
      {
      公共整数比较(派生其他)
      {
      //做比较
      }
      公共覆盖整数比较(基本其他)
      {
      如果(其他是派生的)
      返回CompareTo((派生)其他);
      返回基数。比较(其他);
      }
      }
      
      阅读Eric Lipperts关于过载解决方案的博客文章-阅读Eric Lipperts关于过载解决方案的博客文章-感谢您的努力。我试着变得聪明些,防止这种情况发生