虚拟方法的重载分辨率

Ash*_*ohn 11 c# methods virtual overloading

考虑一下代码

public class Base
{
   public virtual int Add(int a,int b)
   {
      return a+b;
   }
}

public class Derived:Base
{
   public override int Add(int a,int b)
   {
      return a+b;
   }

   public int Add(float a,float b)
   {
      return (Int32)(a + b);
   }
}
Run Code Online (Sandbox Code Playgroud)

如果我创建Derived类的实例并使用int类型的参数调用Add,为什么它使用float参数调用Add方法

Derived obj =new Derived()
obj.Add(3,5)

// why this is calling 
Add(float a,float b)
Run Code Online (Sandbox Code Playgroud)

为什么不调用更具体的方法?

Sve*_*ven 16

这是设计的.C#语言规范的第7.5.3节规定:

例如,方法调用的候选集不包括标记为override的方法(第7.4节),如果派生类中的任何方法适用(第7.6.5.1节),则基类中的方法不是候选方法.

换句话说,因为您的Derived类具有非重写Add方法,Add所以Base类中的方法(及其重写版本Derived)不再是重载决策的候选者.

即使Base.Add(int,int)是更好的匹配,存在Derived.Add(float,float)意味着编译器甚至从不考虑基类方法.

Eric Lippert在这篇博文中讨论了这种设计的一些原因.