虚拟方法的重载分辨率

时间:2011-07-22 12:08:43

标签: 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);
   }
}

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

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

// why this is calling 
Add(float a,float b)

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

2 个答案:

答案 0 :(得分:16)

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

  

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

换句话说,因为您的Derived类具有未覆盖的Add方法,Add类中的Base方法(以及Derived中的重写版本Base.Add(int,int) 1}})不再是重载决策的候选者。

即使Derived.Add(float,float)更匹配,但{{1}}的存在意味着编译器甚至不会考虑基类方法。

Eric Lippert在this blog post中讨论了这种设计的一些原因。

答案 1 :(得分:0)

http://www.yoda.arachsys.com/csharp/teasers-answers.html

在选择重载时,如果派生类中声明了任何兼容方法,则忽略基类中声明的所有签名 - 即使它们在同一派生类中被覆盖!