12

Why should virtual methods be explicitly overridden in C#?

Cristian Diaconescu
  • 34,633
  • 32
  • 143
  • 233
subanki
  • 1,411
  • 10
  • 25
  • 48

5 Answers5

16

By declaring a method as virtual, you are stating your intention that the method can be overridden in a derived class.

By declaring your implementing method as override, your are stating your intention that you are overriding a virtual method.

By requiring that the override keyword be used to override a virtual method, the designers of the language encourage clarity, by requiring you to state your intentions.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • 1
    @George: Because you can only use the abstract modifier in abstract classes. – Jamie Ide Jul 14 '10 at 17:33
  • 3
    @George Stocker - Because you might not want to mark your entire class as abstract (the class needs the abstract modifier to have abstract methods). – Justin Niessner Jul 14 '10 at 17:35
  • The `override` keyword is not required – see my answer. – SLaks Jul 14 '10 at 17:52
  • @SLaks: It *is* if you want to override. – Robert Harvey Jul 14 '10 at 17:53
  • This answer does not mention the default behavior `new` at all. That is, when you are not overriding, you are hiding the base implementation. – Dykam Jul 14 '10 at 17:56
  • 2
    (Copied my comment up here, as it's an important point. Should have made it an answer I guess :-) ...override also allows the compiler to tell us when we make a mistake (e.g. if you add a parameter to the base class method in C++, it breaks all the derived classes but you have no way of knowing it - a cause of some really nasty to trace bugs, because bits of the derived class behaviour just quietly stop working. In C# it gives an error for every override that no longer overrides anything) – Jason Williams Jul 14 '10 at 18:55
11

If you don't add the override keyword, the method will be hidden (as if it had the new keyword), not overridden.

For example:

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

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

This code prints Base. If you add override to the Derived implementation, the code will print Derived.

You cannot do this in C++ with a virtual method. (There is no way to hide a C++ virtual method without overriding it)

kayess
  • 3,384
  • 9
  • 28
  • 45
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 1
    I agree that this should not be legal and should throw a Error instead of a Warning. (Edit: Someone removed his comment above this one). – Dykam Jul 14 '10 at 18:03
10

It is because the C# team members are all skilled C++ programmers. And know how incipient this particular bug is:

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

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

It is a lot more common then you might think. The derived class is always declared in another source code file. You don't typically get this wrong right away, it happens when you refactor. No peep from the compiler, the code runs pretty normal, just doesn't do what you expect it to do. You can look at it for an hour or a day and not see the bug.

This can never happen in a C# program. Even managed C++ adopted this syntax, breaking with native C++ syntax intentionally. Always a courageous choice. IntelliSense takes the sting out the extra verbiage.

There's a lot of syntax tweaks in C# that resemble this kind of bug avoidance syntax.


EDIT: and the rest of the C++ community agreed and adopted the override keyword into the new C++11 language specification.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 1
    +1 Best answer IMO because it explains the"why" behind the language design decision instead of "how virtual calls work" as higher rated answers do... PS. @Hans I seem to be bumping in a lot of pertinent answers written by you these days :) – Cristian Diaconescu Nov 20 '12 at 08:53
5

Because it makes code more readable:

class Derived : Base
{
    void Foo();
}

In C++, Foo may or may not be a virtual method, we can't tell by looking at the definition. In C# we know a method is virtual (or isn't) because there is either a virtual or override keyword.

Jason's comment below is a better answer.

(edited for clarity)

Tergiver
  • 14,171
  • 3
  • 41
  • 68
  • 1
    ... and it gives Intellisense the ability to help us override a method. Type "override" and Intellisense pops up with a choice, and even fills in the entire method signature for us. How awesome is that? – Tergiver Jul 14 '10 at 17:31
  • 5
    ...and, most importantly, it allows the compiler to tell us when we make a mistake (e.g. if you add a parameter to the base class method in C++, it breaks all the derived classes but you have no way of knowing it - a cause of some really nasty to trace bugs, because bits of the derived class behaviour just quietly stop working. In C# it gives an error for every override that no longer overrides anything) – Jason Williams Jul 14 '10 at 17:36
  • _"In C++ it might be, we can't tell by looking at the definition."_ -- By looking at the definition, we can tell that it's not C++ at all. – stakx - no longer contributing Jul 14 '10 at 17:44
  • @stakx: That whooshing sound you heard was you missing the point. – Powerlord Jul 14 '10 at 17:47
  • I think I *do* get the point, _now that I know that there is one._ All in all, I find this answer more confusing than helpful, though. (-1) – stakx - no longer contributing Jul 14 '10 at 17:50
  • 1
    I say this answer is wrong, as adding `override` makes the code behave quite different. – Dykam Jul 14 '10 at 17:54
  • @stakx: You're right, I could have written it in C++, which would have been clearer @Dykam: C# does not allow you to override without the keyword. If there is no override keyword, there cannot be a method with that signature to override. There is no "different behavior" because they are two different things (overridding, not overridding). – Tergiver Jul 14 '10 at 18:03
1

Not all virtual methods should be overridden, though all abstract methods should (and must) be. As for why the 'override' keyword is explicit, that's because overriding and hiding behave differently. A hiding method is not called through a reference to a base class, whereas an overridden method is. This is why the compiler specifically warns about how you should use the 'new' keyword in the case where you are hiding rather than overriding.

Dan Bryant
  • 27,329
  • 4
  • 56
  • 102