Почему подписи, объявленные в базовом классе, игнорируются? - PullRequest
9 голосов
/ 06 сентября 2010
class Base
{
    public virtual void MethodA(int x)
    {
        Console.WriteLine ("In Base Class");
    }
}

class Derived : Base
{
    public override void MethodA(int x)
    {
        Console.WriteLine ("In derived INT)");
    }

    public void MethodA(object o)
    {
        Console.WriteLine ("In derived OBJECT");
    }
}

class Test
{
    static void Main()
    {
        Derived d = new Derived();
        int k = 20;
        d.MethodA(k);
    }
}

Вывод, который я получил для этого: " В производном ОБЪЕКТЕ ". В чем причина этого странного поведения? После некоторых исследований я обнаружил, что причина в подписи, объявленной в базовом классе, игнорируется . Почему они игнорируются?

Ответы [ 2 ]

6 голосов
/ 06 сентября 2010

Это по замыслу и по уважительной причине.Такая конструкция помогает предотвратить проблему хрупкого базового класса.C # был разработан для того, чтобы было проще и безопаснее писать «версионные» компоненты, и это правило является большой частью этого.

Это очень часто задаваемый вопрос.Это один из самых распространенных «ложных сообщений об ошибках», которые мы получаем;то есть кто-то считает, что они обнаружили ошибку в компиляторе, когда на самом деле они нашли функцию.

Описание функции и ее назначение см. в моей статье на эту тему.:

http://blogs.msdn.com/b/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx

Дополнительные статьи о том, как на разных языках решается проблема базового класса хрупких, см. В моем архиве статей на эту тему:

http://blogs.msdn.com/b/ericlippert/archive/tags/brittle+base+classes/

2 голосов
/ 06 сентября 2010

Компилятор в VC # 2008 проверяет доступные не виртуальные функции перед виртуальными, когда решает, что вызывать. Так как ваш класс Derived имеет не виртуальный MethodA (объект), который может быть вызван, компилятор вызывает его.

Если вы добавите виртуальный MethodA (объект) в Base, будет вызван Derived.MethodA (int), потому что тогда MethodA (объект) и MethodA (int) будут виртуальными.

Я недостаточно знаком со спецификацией языка C #, чтобы знать, является ли это заданным поведением, или ошибка в компиляторе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...