Почему виртуальные методы должны быть явно переопределены в C#?

Почему виртуальные методы должны быть явно переопределены в C#?

6 ответов


объявив метод как virtual, вы заявив о своем намерении что метод может быть переопределен в производном классе.

объявив свой метод реализации как override, вы заявив о своем намерении что вы переопределяете virtual метод.

, требованием override ключевое слово используется для переопределения виртуального метода, разработчики языка поощряют ясность, требуя от вас указать свой намерения.


если вы не добавить override ключевое слово, метод будет скрыт (как если бы он имел new ключевое слово), не переопределяются.

например:

class Base {
    public virtual void T() { Console.WriteLine("Base"); }
}
class Derived : Base {
    public void T() { Console.WriteLine("Derived"); }
}

Base d = new Derived();
d.T();

этот код выводит Base. Если добавить override до Derived реализация, код будет печатать Derived.

вы не можете сделать это на C++ с помощью виртуального метода. (невозможно скрыть виртуальный метод C++ без его переопределения)


это потому, что члены команды C# являются квалифицированными программистами C++. И знаете, как зарождается эта конкретная ошибка:

class Base {
protected:
    virtual void Mumble(int arg) {}
};

class Derived : public Base {
protected:
    // Override base class method
    void Mumble(long arg) {}
};

это намного чаще, чем вы могли бы подумать. Производный класс всегда объявляется в другом файле исходного кода. Вы не обычно получить это неправильно сразу, это происходит, когда вы рефакторинг. Нет писка от компилятора, код работает довольно нормально, просто не делает то, что вы ожидаете. Вы можете смотреть на него в течение часа или дня и не видеть жук.

Это никогда не может произойти в программе c#. Даже управляемый C++ принял этот синтаксис, намеренно нарушая собственный синтаксис c++. Всегда смелый выбор. IntelliSense снимает Жало С лишних слов.

в C# есть много синтаксических настроек, которые напоминают такой синтаксис избежания ошибок.


EDIT: и остальная часть сообщества C++ согласилась и приняла переопределить ключевое слово в новый язык C++11 спецификация.


потому что это делает код более читабельным:

class Derived : Base
{
    void Foo();
}

В C++ Foo может быть или не быть виртуальным методом, мы не можем сказать, глядя на определение. В C# мы знаем, что метод является виртуальным (или нет), потому что есть либо виртуальный или ключевое слово override.

комментарий Джейсона ниже-лучший ответ.

(отредактированы для ясности)


Не все виртуальные методы должны быть переопределены, хотя все абстрактные методы должны (и должны) быть. Что касается того, почему ключевое слово override является явным, это потому, что переопределение и скрытие ведут себя по-разному. Метод скрытия не вызывается через ссылку на базовый класс, В то время как переопределенный метод. Вот почему компилятор специально предупреждает о том, как вы должны использовать ключевое слово " new " в случае, когда вы скрываетесь, а не переопределяете.


нет необходимости явно переопределять виртуальный метод в производном классе. Пометка метода virtual включает только переопределение.