ПОЧЕМУ виртуальные методы должны быть явно переопределены в C#?

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

12
задан Cristi Diaconescu 20 November 2012 в 08:51
поделиться

5 ответов

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

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

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

16
ответ дан 2 December 2019 в 03:28
поделиться

Если вы не добавите ключевое слово 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 . Если вы добавите переопределение в реализацию Derived , код напечатает Derived .

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

11
ответ дан 2 December 2019 в 03:28
поделиться

Это потому, что все члены команды 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 ++ согласились и приняли ключевое слово override в новую спецификацию языка C ++ 11.

10
ответ дан 2 December 2019 в 03:28
поделиться

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

1
ответ дан 2 December 2019 в 03:28
поделиться

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

class Derived : Base
{
    void Foo();
}

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

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

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

5
ответ дан 2 December 2019 в 03:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: