Почему виртуальные методы должны быть явно переопределены в C #? - PullRequest
12 голосов
/ 14 июля 2010

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

Ответы [ 5 ]

16 голосов
/ 14 июля 2010

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

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

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

11 голосов
/ 14 июля 2010

Если вы не добавите ключевое слово 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 ++ без переопределения его )

10 голосов
/ 14 июля 2010

Это потому, что все члены команды 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 # есть множество доработок синтаксиса, которые напоминают синтаксис такого рода для избежания ошибок.


РЕДАКТИРОВАТЬ: и остальное сообщество C ++ согласилось и приняло ключевое слово override в новой спецификации языка C ++ 11.

5 голосов
/ 14 июля 2010

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

class Derived : Base
{
    void Foo();
}

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

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

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

1 голос
/ 14 июля 2010

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

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