Разрешение перегрузки виртуальных методов
Рассмотрим код
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 с параметрами float
Derived obj =new Derived()
obj.Add(3,5)
// why this is calling
Add(float a,float b)
Почему он не вызывает более специфический метод?
Ответы
Ответ 1
Это по дизайну. В разделе 7.5.3 спецификации языка С# указано:
Например, набор кандидатов для вызова метода не включает переопределенные методы (§7.4), а методы в базовом классе не являются кандидатами, если применим какой-либо метод в производном классе (§7.6.5.1).
Другими словами, поскольку ваш класс Derived
имеет непереопределенный метод Add
, метод Add
в классе Base
(и его переопределенная версия в Derived
) больше не является кандидатом на перегрузку разрешение.
Даже если Base.Add(int,int)
будет лучшим совпадением, существование Derived.Add(float,float)
означает, что метод базового класса даже не рассматривается компилятором.
Эрик Липперт обсуждает некоторые причины этого проекта в этом сообщении в блоге.
Ответ 2
http://www.yoda.arachsys.com/csharp/teasers-answers.html
при выборе перегрузки, если есть какие-либо совместимые методы, объявленные в производном классе, все сигнатуры, объявленные в базовом классе, игнорируются - даже если они переопределены в одном и том же производном классе!