WHy should virtual methods be explicitly overridden in C#? - c#

Why should virtual methods be explicitly overridden in C#?

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.

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)

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.

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)

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.

Related

Why is it required to have override keyword in front of abstract methods when we implement them in a child class?

When we create a class that inherits from an abstract class and when we implement the inherited abstract class why do we have to use the override keyword?
public abstract class Person
{
public Person()
{
}
protected virtual void Greet()
{
// code
}
protected abstract void SayHello();
}
public class Employee : Person
{
protected override void SayHello() // Why is override keyword necessary here?
{
throw new NotImplementedException();
}
protected override void Greet()
{
base.Greet();
}
}
Since the method is declared abstract in its parent class it doesn't have any implementation in the parent class, so why is the keyword override necessary here?
When we create a class that inherits from an abstract class and when we implement the inherited abstract class why do we have to use the override keyword?
"Why?" questions like this can be hard to answer because they are vague. I'm going to assume that your question is "what arguments could be made during language design to argue for the position that the override keyword is required?"
Let's start by taking a step back. In some languages, say, Java, methods are virtual by default and overridden automatically. The designers of C# were aware of this and considered it to be a minor flaw in Java. C# is not "Java with the stupid parts taken out" as some have said, but the designers of C# were keen to learn from the problematic design points of C, C++ and Java, and not replicate them in C#.
The C# designers considered overriding to be a possible source of bugs; after all, it is a way to change the behaviour of existing, tested code, and that is dangerous. Overriding is not something that should be done casually or by accident; it should be designed by someone thinking hard about it. That's why methods are not virtual by default, and why you are required to say that you are overriding a method.
That's the basic reasoning. We can now go into some more advanced reasoning.
StriplingWarrior's answer gives a good first cut at making a more advanced argument. The author of the derived class may be uninformed about the base class, may be intending to make a new method, and we should not allow the user to override by mistake.
Though this point is reasonable, there are a number of counterarguments, such as:
The author of a derived class has a responsibility to know everything about the base class! They are re-using that code, and they should do the due diligence to understand that code thoroughly before re-using it.
In your particular scenario the virtual method is abstract; it would be an error to not override it, and so it is unlikely that the author would be creating an implementation by accident.
Let's then make an even more advanced argument on this point. Under what circumstances can the author of a derived class be excused for not knowing what the base class does? Well, consider this scenario:
The base class author makes an abstract base class B.
The derived class author, on a different team, makes a derived class D with method M.
The base class author realizes that teams which extend base class B will always need to supply a method M, so the base class author adds abstract method M.
When class D is recompiled, what happens?
What we want to happen is the author of D is informed that something relevant has changed. The relevant thing that has changed is that M is now a requirement and that their implementation must be overloaded. D.M might need to change its behaviour once we know that it could be called from the base class. The correct thing to do is not to silently say "oh, D.M exists and extends B.M". The correct thing for the compiler to do is fail, and say "hey, author of D, check out this assumption of yours which is no longer valid and fix your code if necessary".
In your example, suppose the override was optional on SayHello because it is overriding an abstract method. There are two possibilities: (1) the author of the code intends to override an abstract method, or (2) the overriding method is overriding by accident because someone else changed the base class, and the code is now wrong in some subtle way. We cannot tell these possibilities apart if override is optional.
But if override is required then we can tell apart three scenarios. If there is a possible mistake in the code then override is missing. If it is intentionally overriding then override is present. And if it is intentionally not overriding then new is present. C#'s design enables us to make these subtle distinctions.
Remember compiler error reporting requires reading the mind of the developer; the compiler must deduce from wrong code what correct code the author likely had in mind, and give an error that points them in the correct direction. The more clues we can make the developer leave in the code about what they were thinking, the better a job the compiler can do in reporting errors and therefore the faster you can find and fix your bugs.
But more generally, C# was designed for a world in which code changes. A great many features of C# which appear "odd" are in fact there because they inform the developer when an assumption that used to be valid has become invalid because a base class changed. This class of bugs is called "brittle base class failures", and C# has a number of interesting mitigations for this failure class.
It's to specify whether you're trying to override another method in the parent class or create a new implementation unique to this level of the class hierarchy. It's conceivable that a programmer might not be aware of the existence of a method in a parent class with exactly the same signature as the one they create in their class, which could lead to some nasty surprises.
While it's true that an abstract method must be overridden in a non-abstract child class, the crafters of C# probably felt it's still better to be explicit about what you're trying to do.
Because abstract method is a virtual method with no implementation, per C# language specification, means that abstract method is implicitly a virtual method. And override is used to extend or modify the abstract or virtual implementation, as you can see here
To rephrase it a little bit - you use virtual methods to implement some kind of late binding, whereas abstract methods force the subclasses of the type to have the method explicitly overridden. That's the point, when method is virtual, it can be overridden, when it's an abstract - it must be overriden
To add to #StriplingWarrior's answer, I think it was also done to have a syntax that is consistent with overriding a virtual method in the base class.
public abstract class MyBase
{
public virtual void MyVirtualMethod() { }
public virtual void MyOtherVirtualMethod() { }
public abstract void MyAbtractMethod();
}
public class MyDerived : MyBase
{
// When overriding a virtual method in MyBase, we use the override keyword.
public override void MyVirtualMethod() { }
// If we want to hide the virtual method in MyBase, we use the new keyword.
public new void MyOtherVirtualMethod() { }
// Because MyAbtractMethod is abstract in MyBase, we have to override it:
// we can't hide it with new.
// For consistency with overriding a virtual method, we also use the override keyword.
public override void MyAbtractMethod() { }
}
So C# could have been designed so that you did not need the override keyword for overriding abstract methods, but I think the designers decided that would be confusing as it would not be consistent with overriding a virtual method.

Is there a C# equivalent of Java's #Override?

This has been asked before, but I could not get clarity from that answer, that's why I ask again...
Let's use two examples:
class implements interface
class extends an abstract class
My feeling is that with respect to the override keyword, both samples must behave identically. What is the desired goal of override? To prevent a method being dropped in a superclass or interface without being changed in all subclasses or implementing classes. So a compile time code consistency check.
In this C# code, compiling results in error: '....RepositoryContext.getXmlDoc()': no suitable method found to override:
interface IRepositoryContext
{
XmlDocument getXmlDoc();
}
class RepositoryContext : IRepositoryContext
{
private readonly XmlDocument gXmlDoc = new XmlDocument();
public override XmlDocument getXmlDoc() // does not compile
{
return gXmlDoc;
}
}
Whereas in this C# code, compilation works without any errors or warnings:
abstract class RepositoryContextBase
{
public abstract XmlDocument getXmlDoc();
}
class RepositoryContext : RepositoryContextBase
{
private readonly XmlDocument gXmlDoc = new XmlDocument();
public override XmlDocument getXmlDoc()
{
return gXmlDoc;
}
}
Is it a valid assumption that this should not work identically, or is there a way around this, or...?
The override modifier is defined thus:
The override modifier is required to extend or modify the abstract or virtual implementation of an inherited method, property, indexer, or event.
http://msdn.microsoft.com/en-us/library/ebca9ah3.aspx
The override keyword specifies that the method overrides an existing method implementation, which is why you don't need to specify it when you're implementing an interface directly - there is no such method to override; you're the first to implement it.
When you use the override keyword, you're essentially saying "for this class, call this method instead of the base method." This obviously doesn't apply when there is no such base method (e.g. when you are directly implementing an interface).
For virtual or abstract methods from classes, you need to insert the override keyword or it won't work at all.
For interfaces, there is no equivalent.
However, interface implementations must implement all of their base methods, so forgetting a method will usually give you a compiler error.
This makes it less important.
In the first example it's an interface you're implementing. You can't override something when you're the only implementer in the inheritance chain.
In the second example you've inherited from a concrete implementation and stated that you want to implement the abstract member and the syntax for that (albeit not literally an override as much as an implementation) is the override keyword. However, you are in fact overriding the chain you're a part of because you're implementing it.
So think of the override keyword more in relation to the fact that you're ensuring your implementation gets called instead of the base class when it's called on an instance of the inheritor.
This too explains why you must explicitly call base.Member() inside the override because you've overriden the chain.
Another OO concept to remember is that the same effect can be achieve on methods that aren't abstract or virtual. Members can in fact be hidden and you don't have to specify them with the new keyword.
With that being said it should help abstract for you the idea that these are very much just language features or maybe better said it's just syntax.
In your first example you are implementing an interface. In this case you do not have to specify the override keyword, simply remove it.
Seems like you have a misconception regarding interface implementation vs. inheritance.
Interface implementations are completely different from inheritance. With an interface, you statically (i.e. at compile time) enforce the presence of certain method signatures. Therefore, any keywords like override or the like are just plain wrong in such a context.
Inheritance on the contrary is causing runtime polymorphism through a virtual method table (basically a list of method adresses).
You can see this also from the fact that, in C#, you can implement as many interfaces as you like, whereas multiple inheritance is forbidden.
The reason is that there is a fundamental difference between implementing an interface and overriding a method.
In order to fully implement an interface, you have to provide implementations for all of methods and/or properties but those implementations do not necessarily have to be overrideable in turn. The compiler wants you to be very specific about your intentions when you create a method, because you may have one of a range of behaviours in mind, and it wants to be sure which one you mean.
The override keyword means "I am overriding the base class' implementation with this one". If when implementing an interface, there is no base implementation, then it doesn't apply. You use virtual to indicate an overrideable method with no base implementation, and omit both override and virtual otherwise.
So given this interface:
interface IFoo
{
void Bar();
}
This class implements that interface, and permits classes to inherit from it in turn and override that implementation (since unlike in e.g. Java, methods in C# are not virtual by default):
class Foo : IFoo
{
public virtual void Bar() { ... } // compiles
}
class DerivedFoo : Foo
{
public override void Bar() { ... } // compiles, and may choose to call base.Bar()
}
Whereas this class implements that interface, and does not permit overrides:
class Foo : IFoo
{
public void Bar(); // compiles
}
class DerivedFoo : Foo
{
public override void Bar() { ... } // does NOT compile; Foo.Bar() is not virtual (overrideable)
}
There are in fact more possiblities than that, including:
You can create an abstract base class which implements an interface, but only provide abstract implementations for some/all methods.
You can explicitly implement an interface method
You can seal an overriding method to prevent further overrides
You can create a new method with the same name which is unrelated to the base class' method of that name
There are more details on MSDN.
If you aren't specific enough for the compiler, it will warn you or throw an error.
Update
The reason the compiler complains in the second example above, is that you will not get polymorphic behaviour. That is, if someone has a reference to Foo and calls Bar(), they will get Foo's implementation, not DerivedFoo's. This is because Bar.Foo is not in the virtual method table. Put another way, in C#, the default when compared to Java is that all methods are final unless you say otherwise.
From your comments it sounds like you're trying to get a warning or error in the case where, in my first example above, you then change IFoo by removing the Bar method entirely. (Obviously if you just change the method signature, you'll get a suitable compile error as you'd hope.)
You can achieve this by explicitly implementing the method:
class Foo : IFoo
{
void IFoo.Bar() { ... }
}
Then if the interface changes, you will get a compile error. However, this means derived classes can no longer override Foo's implementation; if you want that behaviour as well, you need:
class Foo : IFoo
{
void IFoo.Bar() { ... }
protected /* or public */ virtual void Bar()
{
IFoo foo = this; // declare rather than cast, to get compile error not runtime exception
foo.Bar();
}
}
You will still get compile errors if you remove the method, both from your explicit and other implementation.
Bear in mind that the explicit implementation is only available to callers with a reference to an IFoo, not a Foo. But if as in the above code you do add a public method which, for example, delegates to the explicit IFoo implementation, that won't be a problem (and it doesn't have to be virtual unless you want it overrideable).
This is an approach that works; whether it's overkill is a matter of taste, but I can see the merit in removing redundant code as part of refactoring, provided the classes are not public and/or not used outside your assembly. However instead of factoring code in this fashion I'd recommend using a tool such as ReSharper which will warn you about unused methods.

Preventing a C# subclass from overwriting a method

Say I have an abstract parent class called "Parent" that implements a method called "DisplayTitle". I want this method to be the same for each subclass that inherits "Parent" - I would like a compile error if a subclass attempts to implement their own "DisplayTitle" method. How can I accomplish this in C#. I believe in Java, I'd just mark the method as "final", but I can't seem to find an alternative in C#. I've been messing around with "sealed" and "override", but I can't get the behavior that I'm looking for.
For example, in this code:
using System;
namespace ConsoleApplication1
{
class Parent
{
public void DisplayTitle() { Console.WriteLine("Parent's Title"); }
}
class ChildSubclass : Parent
{
public void DisplayTitle() { Console.WriteLine("Child's Own Implementation of Title");
}
static void Main(string[] args)
{
ChildSubclass myChild = new ChildSubclass();
myChild.DisplayTitle();
Console.ReadLine();
}
}
}
I'd like to receive a compile error saying that the "ChildSubClass" can't override "DisplayTitle". I currently get a warning - but it seems like this is something that I should be able to do and I don't know the proper attributes to label the method.
How can I accomplish this in C#. I believe in Java, I'd just mark the method as "final", but I can't seem to find an alternative in C#.
The rough equivalent is sealed in C#, but you normally only need it for virtual methods - and your DisplayTitle method isn't virtual.
It's important to note that ChildSubclass isn't overriding DisplayTitle - it's hiding it. Any code which only uses references to Parent won't end up calling that implementation.
Note that with the code as-is, you should get a compile-time warning advising you to add the new modifier to the method in ChildSubclass:
public new void DisplayTitle() { ... }
You can't stop derived classes from hiding existing methods, other than by sealing the class itself to prevent the creation of a derived class entirely... but callers which don't use the derived type directly won't care.
What's your real concern here? Accidental misuse, or deliberate problems?
EDIT: Note that the warning for your sample code would be something like:
Test.cs(12,19): warning CS0108:
'ConsoleApplication1.ChildSubclass.DisplayTitle()' hides inherited
member 'ConsoleApplication1.Parent.DisplayTitle()'. Use the new keyword
if hiding was intended.
I suggest you turn warnings into errors, and then it's harder to ignore them :)
A derived class cannot override your method, you didn't declare it virtual. Note how that's very different in C# compared to Java, all methods are virtual in Java. In C# you must explicitly use the keyword.
A derived class can hide your method by using the same name again. This is probably the compile warning you are talking about. Using the new keyword suppresses the warning. This method does not in any way override your original method, your base class code always calls the original method, not the one in the derived class.
Use the sealed modifier to prevent subclasses from overriding your classes, properties, or methods. What isn't working when you use sealed?
http://msdn.microsoft.com/en-us/library/88c54tsw.aspx
I'm fairly certain that what you want is not possible in C# using method modifier keywords.
Sealed only applies when overriding a virtual method in an ancestor class, which then prevent further overriding.

create mustoveride function with code in it

I have a MustInherit class with some MustOveride Methods in it. When i inherit form that class, I automatically get the MustOveride Methods or properties.
My question is, I want to be able, to inherit from a class, get my MustOveride functions and methods, but then with some code already in it. I've once seen a .net class that did it, when I inherited from that class, I got the methods, with some comments in it.
Does anybody have an idea what i mean? (It a bit hard to describe ;-) )
I think what you described is known as Template Method Pattern:
public abstract class MyClass
{
public void SomeMethod()
{
// code
MustInherit();
// code
}
protected abstract void MustInherit();
}
Create a method which will not be overridden SomeMethod in this sample and stuff all common code into this class. Then create an abstract method which must be overridden.
If you want to provide a default implementation, so the method must not be overridden but can be use the virtual keyword.
public abstract class MyClass
{
public void SomeMethod()
{
// code
MustInherit();
// code
}
protected virtual void CanInherit()
{
// default implementation
}
}
I assume, you want to do have the following:
When you inherit from that abstract base class, you want to have those abstract methods already partly implemented in your class.
This is not possible out of the box. It could be achieved with some templating, but that has nothing to do with C# or VB.NET but with the IDE used.
The only thing you can do is to create that method as virtual (C# - I don't know how it is called in VB.NET) in the base class and call the base implementation in the derived class.
An Abstract class for you service :)
If you need that consumer of your abstract class ovverides some methods for sure then mark them as abstract too. If you need just to provide possibility of ovveriding you methods but this is not definitely necessary then mark them as virtual.
With the virtual keyword you are not forced to implement the inherited method, then it will use the default implementation of the base class. In that way, you kind of inherit all the code from the base method.
Otherwise, you can implement you own derived version of the method, and somewhere in it call the base class' version of method : base.MethodName(...);. That allow you to kind of inherit all the code from the base method once again, but this time with additional code before and after which is specific to your derived class.
Otherwise, you can make your base class' method such that it uses delegates in its code and call it here and there. Thus the fundamental functioning of the base class' method remain the same for all the derived classes, but each derived class provides its own delegates to adjust some detail key blocks of code in the base class' method.
Otherwise, if you want to see partially implemented methods with comments here and there like Add your code here, it's typically a matter of code generated by an external tool like Visual Studio or another IDE and has nothing to do with the language itself.
But as you see there are plenty of possibilities, depending of you you want precisely...

Why does this C# class declaration compile?

This question really is kinda pointless, but I'm just curious:
This:
public sealed class MyClass
{
protected void MyMethod(){}
}
compiles, but gives a warning
while This:
public sealed class MyClass
{
public virtual void MyMethod(){}
}
doesn't compile. Just out of sheer curiosity, is there a reason for this?
virtual is used to declare a method/property "override-able".
sealed is used to declare that class cannot be inherited from.
So a virtual method in a sealed class could never be overridden, as the class could never be inherited from. It just doesn't make sense.
protected affects access to a member, it does not declare it "override-able" as virtual does (though it is often used in that manner) and is accordingly not contradictory.
The only reason I can think of is that sometimes you would need to write protected methods to override other protected methods. The language could have been designed to allow this:
protected override void Foo()
but not this
protected void Foo()
but that might have been seen to be a little hard to follow - it's the absence of override which makes it useless, whereas in the case of
public virtual void Foo()
it's the presence of virtual that is useless. The presence of something "wrong" is probably easier to understand than the absence of something useful.
In this case, being virtual may also have performance implications, whereas making something protected instead of private probably doesn't - so it's a bit more severe.
These are just guesses though really - if we're really lucky, Eric Lippert will give a more definitive answer. He's the one you want, not me :)
Best answer: treat warnings as errors and they're equivalent anyway ;)
I can't see a good reason for this. The protected MyMethod can be called from MyClass, but will never be called from a derived class (because MyClass is sealed). The virtual version is also allowed to be called directly from MyClass, but it is illegal for the method to have an override because you can't derive a class from MyClass...
A sealed class can have protected members via inheritance.
When a method is part of a class, it doesn't matter how that method got there.
In the first case, with the protected method on the sealed class, its the same as if the sealed class inherited a protected method. So it compiles.
Out of curiosity, what exactly is the warning given?
The error is:
CS0549: 'function' is a new virtual member in sealed class 'class'.
First of all, despite the fact that it doesn't really make sense to include new protected or virtual members in a sealed class, the CLI¹ does allow it. The CLI also allows calling members of a sealed class using the callvirt IL instruction, even though a compiler could freely replace it with the call instruction.
Currently, I can't find anything in ECMA-334 (C# Language Specification) that requires the compiler emit the above error. It appears like a Microsoft's implementation added the error just because it doesn't make sense to include new virtual members in a sealed class.
¹The CLI is a virtual machine, and the C# compiler emits byte code that runs on it. Almost any concept that's illegal in the CLI is also illegal in C# for that reason - but this is a case where C# does a little extra (not that it's a problem).
Edit: It seems to posts getting marked up are explaining why it doesn't make sense to write code like that in the OP. But regarding what rule made it a compiler error they appear to be wrong.
A sealed class cannot be sub-classed, therefore virtual is not an option. Thus error.
This first is a bit silly but valid, thus warning.
I'd guess the compiler does some optimizations with sealed classes that are impossible if you have a virtual method declared - "not having a vtable" seems a likely candidate.
That's just a guess, though.
As sealed When applied to a class, the sealed modifier prevents other classes from inheriting from it.
here i am trying to explain you one by one:
public sealed class MyClass
{
protected void MyMethod(){}
}
it gives you warning because practically it make no sense because after declaring a class as sealed you can't inherits it and as your method is protected so you can't access it outside the class using it's object(and keep also in mind that you can't create a child class of this so you can't use this method by that trick also).So practically it makes no sense to making it protected so compiler gives you a warning but if you make it as public or internal then it will not gives you error because it's useful in that case.
now the second one:
public sealed class MyClass
{
public virtual void MyMethod(){}
}
as you sealed you class and now you are making your method as virtual so indirectly you are giving a offer to someone to override it and that can be only possible by inheritance and here comes the issue.That you class is sealed so you can't perform inheritance with this class.so that's why with virtual it gives error.
i hope it will help you to understand.
for reference http://msdn.microsoft.com/en-us/library/88c54tsw.aspx
Declaring a new protected member implies an intent to share that member with descendent classes. A sealed class cannot have descendents, so declaring a new protected member is a bit of an oxymoron, just as declaring a new virtual method in a sealed class.
As for why virtual produces an error while protected only produces a warning, I can only speculate that perhaps it has to do with the fact that new virtual methods require the compiler to build data structures for the type (a vtable), whereas new protected members only have an access flag set - no new data structure. If the compiler is prohibited from creating a vtable for a sealed class, what should it do if it encounters a new virtual method? Fail the compile. A new protected method in a sealed class is pointless but doesn't required the compiler to venture into forbidden territory.

Categories

Resources