为什么要在C#中显式覆盖虚方法?

sub*_*nki 12 .net c# virtual inheritance

为什么要在C#中显式覆盖虚方法?

Rob*_*vey 16

通过声明一个方法virtual,您表明您的意图是可以在派生类中重写该方法.

通过声明您的实现方法override,您表明您打算覆盖virtual方法.

通过要求使用override关键字来覆盖虚拟方法,语言的设计者通过要求您陈述您的意图来鼓励清晰.

  • @George Stocker - 因为您可能不希望将整个类标记为抽象类(该类需要抽象修饰符才能使用抽象方法). (3认同)
  • (在这里复制我的评论,因为它是一个重要的观点.应该让它成为一个答案我猜:-) ... override还允许编译器告诉我们何时出错(例如,如果你向基础添加一个参数在C++中的类方法,它打破了所有派生类,但你无法知道它 - 一些真正讨厌错误的原因,因为派生类行为的位只是悄然停止工作.在C#中它给每个错误覆盖不再覆盖任何东西) (2认同)

SLa*_*aks 11

如果您不添加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();
Run Code Online (Sandbox Code Playgroud)

此代码打印Base.如果添加overrideDerived实现中,代码将打印出来Derived.

您不能使用虚方法在C++中执行此操作.(没有覆盖它就无法隐藏C++虚方法)


Han*_*ant 10

这是因为C#团队成员都是熟练的C++程序员.并且知道这个特定的bug是多么早期:

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

class Derived : public Base {
protected:
    // Override base class method
    void Mumble(long arg) {}
};
Run Code Online (Sandbox Code Playgroud)

这比你想象的要普遍得多.派生类始终在另一个源代码文件中声明.你通常不会马上弄错,它会在你重构的时候发生.没有窥视编译器,代码运行正常,只是没有做你期望它做的事情.您可以查看它一小时或一天而不会看到错误.

这在C#程序中永远不会发生.即使是托管C++也采用了这种语法,故意打破本机C++语法.永远是一个勇敢的选择.IntelliSense消除了额外的措辞.

C#中有很多语法调整,类似于这种错误避免语法.


编辑:其余的C++社区同意并将override关键字引入新的C++ 11语言规范.


Ter*_*ver 5

因为它使代码更具可读性:

class Derived : Base
{
    void Foo();
}
Run Code Online (Sandbox Code Playgroud)

在C++中,Foo可能是也可能不是虚方法,我们无法通过查看定义来判断.在C#中,我们知道一个方法是虚拟的(或者不是),因为有一个virtual或override关键字.

杰森在下面的评论是一个更好的答案.

(为清晰起见编辑)

  • ...而且,最重要的是,它允许编译器告诉我们何时出错(例如,如果在C++中向基类方法添加参数,它会破坏所有派生类,但您无法知道它 - 一些非常讨厌bug的原因,因为派生类行为的位只是悄然停止工作.在C#中,它为每个不再覆盖任何覆盖的覆盖提供错误) (5认同)