Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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

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

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

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

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

В С# существует множество синтаксических твитов, которые напоминают синтаксис синтаксиса ошибок.


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

Ответ 4

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

class Derived : Base
{
    void Foo();
}

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

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

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

Ответ 5

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

Ответ 6

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