Overload resolution of virtual methods

2019-01-25 09:38发布

问题:

Consider the code

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);
   }
}

If I create an instance of Derived class and call Add with parameters of type int why it is calling the Add method with float parameters

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

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

Why it is not calling the more specific method?

回答1:

This is by design. Section 7.5.3 of the C# language specification states:

For example, the set of candidates for a method invocation does not include methods marked override (§7.4), and methods in a base class are not candidates if any method in a derived class is applicable (§7.6.5.1).

In other words, because your Derived class has a non-overridden Add method, the Add method in the Base class (and its overridden version in Derived) are no longer candidates for overload resolution.

Even though Base.Add(int,int) would be a better match, the existance of Derived.Add(float,float) means that the base class method is never even considered by the compiler.

Eric Lippert discusses some of the reasons for this design in this blog post.



回答2:

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

when choosing an overload, if there are any compatible methods declared in a derived class, all signatures declared in the base class are ignored - even if they're overridden in the same derived class!