Разрешение перегрузки виртуальных методов - PullRequest
11 голосов
/ 22 июля 2011

Рассмотрим код

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 и вызываю Add с параметрами типа int, почему он вызывает метод Add с параметрами с плавающей точкой

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

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

Почему не вызывается более конкретный метод?

Ответы [ 2 ]

16 голосов
/ 22 июля 2011

Это по замыслу.Раздел 7.5.3 спецификации языка C # гласит:

Например, набор кандидатов для вызова метода не включает методы, отмеченные переопределением (§7.4), а методы в базовом классе не являютсякандидаты, если какой-либо метод в производном классе применим (§7.6.5.1).

Другими словами, поскольку в вашем классе Derived есть неопределяемый метод Add, Addметод в классе Base (и его переопределенная версия в Derived) больше не являются кандидатами для разрешения перегрузки.

Даже если Base.Add(int,int) будет лучшим соответствием, наличие Derived.Add(float,float) означает, чтометод базового класса даже не рассматривается компилятором.

Эрик Липперт обсуждает некоторые причины такого дизайна в этом сообщении в блоге .

0 голосов
/ 26 июля 2011

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

при выборе перегрузки, если есть какие-либо совместимые методы, объявленные в производном классе, все сигнатуры, объявленные в базовом классе, игнорируются - даже если они переопределены в том же производном классе!

...