C # Virtual and Overriding Keywords

I thought that I had it nailed, and then I will go and look at some source at work, and I wondered why there are so many contradictions in what I read from msdn and what I see in the source .. ..

I understand that the virtual keyword can be used in method declarations to allow any classes that make a selection to override it.

Instead, the override keyword should be used in a derived class when implementing a virtual superclass method ....

For example:

public abstract class A { public virtual string GetName(); } public class B:A { //assume there are some defined properties. public override string GetName() { return FirstName; } } 

I have a few questions:

1) Is it really necessary to define a method as virtual if it has no implementation? Of course, you can simply overwrite it in a subclass without using virtual ones and override it?

2) If (1) is incorrect, I understand correctly that each virtual method must be redefined in a subclass using it ....

EDIT:

You are right, my code will not compile ... I want to know why ... I kept your answers, but then I saw this:

 public abstract class RequestHandler<TRequest, TResponse> : RequestHandler, IRequestHandler<TRequest>, IRequestHandler, IDisposable, ITypedRequestHandler where TRequest : global::Agatha.Common.Request where TResponse : global::Agatha.Common.Response, new() { protected RequestHandler(); public virtual void AfterHandle(TRequest request); public virtual void BeforeHandle(TRequest request); public override Response CreateDefaultResponse(); public TResponse CreateTypedResponse(); public override Response Handle(Request request); public abstract Response Handle(TRequest request); } 

The above does not make the compiler complain ...

+7
source share
7 answers

Firstly, the above code is invalid. The virtual method still needs to have a body with a default implementation. in order to do what you did above, you will need to use abstract keyaord instead of virtual.

abstract means that the body of the method does not exist, but that any class deriving from it must implement this method (if it is not abstract too).

I think this pretty much answers your questions ....

  • If it has no implementation, it cannot be virtual; it must be abstract. If he has an implementation that just does nothing, then this should be implemented.

  • The whole point of a virtual class is that it has default behavior, so you can choose whether to override it. If it were abstract, you would have to redefine it (unless you derived another abstract class).

+10
source

Is it really necessary to define a method as virtual if it has no implementation?

You can make the method abstract (it will implicitly make it virtual).

Surely you can simply overwrite it in a subclass without using a virtual one and override it?

If you simply β€œrewrite” it without explicitly overriding it, it will not be the same method , and calling the method for the base class variable will not call the derived method (it will not participate in polymorphism). You will simply β€œhide” the base class method (the compiler really warns you about this, if this is really what you want to do, you should use the new modifier.)

An example will simplify:

 class B { public virtual void M() { Console.WriteLine("BM") }; } class D1 : Base { // Hides the base method public new void M() { Console.WriteLine("D1.M") }; } class D2 : Base { // Overrides the base method public override void M() { Console.WriteLine("D2.M") }; } ... D1 d1 = new D1(); d1.M(); // Prints "D1.M" B b1 = d1; b1.M(); // Prints "BM", because D1.M doesn't override BM D2 d2 = new D1(); d2.M(); // Prints "D2.M" B b2 = d2; b2.M(); // Also prints "D2.M", because D2.M overrides BM 

If (1) is incorrect, I understand correctly that each virtual method must be overridden in a subclass using it ....

No, only if it is abstract ... a virtual method can have an implementation, in which case derived classes are not forced to redefine it.

+2
source

1) Is it really necessary to define a method as virtual if it has no implementation? Of course, you can simply overwrite it in a subclass without using virtual ones and override it?

As stated in other answers, virtual methods must have implementations. You confuse it with abstract .

If you asked the question whether virtual methods should be declared that should have an implementation, virtual : In C #, yes, this is necessary. In Java, you can override any old method. C #'s solution was to require an override, which can be resolved using the virtual , so methods cannot be overridden if they are not intended for the programmer.

If the programmer has not expressed his intentions without using virtual , you can still override the methods using the new keyword. However, this works differently. Hope this code helps illustrate the concept:

 class Program { static void Main(string[] args) { var baseC = new BaseClass(); var extC = new ExtClass(); var lazyC = new LazyClass(); Console.WriteLine(baseC.NewMethod()); Console.WriteLine(baseC.VirtualOverrideMethod()); Console.WriteLine("---"); Console.WriteLine(extC.NewMethod()); Console.WriteLine(extC.VirtualOverrideMethod()); Console.WriteLine("---"); Console.WriteLine(((BaseClass) extC).NewMethod()); Console.WriteLine(((BaseClass) extC).VirtualOverrideMethod()); // Redundant typecast Console.WriteLine("---"); Console.WriteLine(lazyC.VirtualOverrideMethod()); Console.ReadKey(); } public class BaseClass { public BaseClass() { } public string NewMethod() { return "NewMethod of BaseClass"; } public virtual string VirtualOverrideMethod() { return "VirtualOverrideMethod of BaseClass"; } } class ExtClass : BaseClass { public new string NewMethod() { return "NewMethod of ExtClass"; } public override string VirtualOverrideMethod() { return "VirtualOverrideMethod of ExtClass"; } } class LazyClass : BaseClass { } } 

Output:

 NewMethod of BaseClass VirtualOverrideMethod of BaseClass --- NewMethod of ExtClass VirtualOverrideMethod of ExtClass --- NewMethod of BaseClass VirtualOverrideMethod of ExtClass --- VirtualOverrideMethod of BaseClass 

2) If (1) is incorrect, I understand correctly that each virtual method must be redefined in a subclass using it ....

Not at all. virtual is a way of saying, "It's okay if you want to override this method." In fact, I included LazyClass in my code above to show this.

The above does not make the compiler complain ...

I have not used the interfaces a lot, but this seems like one thing. In my code, if I change

  class ExtClass : BaseClass { public new string NewMethod() { return "NewMethod of ExtClass"; } public override string VirtualOverrideMethod() { return "VirtualOverrideMethod of ExtClass"; } } 

in

  class ExtClass : BaseClass { public new string NewMethod() { return "NewMethod of ExtClass"; } public override string VirtualOverrideMethod() { return "VirtualOverrideMethod of ExtClass"; } } 

I get:

 error CS0501: 'OverrideTest.Program.ExtClass.VirtualOverrideMethod()' must declare a body because it is not marked abstract, extern, or partial 

From Visual Studio 2010. The same goes for the virtual method of my BaseClass .

+1
source

ok, declaring the method virtual (and not wanting to override the method in the subclass), you must enter the world of the hiding method if you must enter the method with the same name in the subclass. You should define it like this:

 public abstract class A { public virtual string GetName() { return null; } } public class B : A { //assume there are some defined properties. public new string GetName() { return FirstName; } } 

I would recommend you think about abstract overriding:

 public abstract class A { public abstract string GetName() } // to override public class B : A { //assume there are some defined properties. public override string GetName() { return FirstName; } } 

that would be very different. I highly recommend that you simply override the abstract method in a subclass.

However, here is a brief description of the topic (old but good reading):

http://www.akadia.com/services/dotnet_polymorphism.html

0
source

The need for virtual dictated by polymorphism. Think about what happens if you override a method in a subclass with new :

 class Parent { void Foo() { Console.WriteLine("Parent"); } virtual void Bar { Console.WriteLine("Parent"); } } class Child : Parent { new void Foo() { Console.WriteLine("Child"); } // another method Foo override void Bar { Console.WriteLine("Child"); } } var child = new Child(); // a Child instance var parent = (Parent)child; // same object, but statically typed as Parent c.Bar(); // prints "Child" p.Bar(); // again, prints "Child" -- expected virtual behavior c.Foo(); // prints "Child" p.Foo(); // but this prints "Parent"!! 

For this reason, classes that should be derived from (i.e. not sealed ) should always mark methods that can be overridden as virtual - otherwise there will be confusing runtime behavior, as described above. It makes no difference if the parent implementation is really doing something or not; The fact is that it behaves differently.

0
source

The exact difference between the virtual and abstract method:

A virtual method can be overridden by derived classes, if selected. A virtual method may or may not have a default implementation for inheritors that execute using the base keyword.

The abstract method must be overridden by derived classes. Its limitations:

  • It can only be defined in an abstract class.
  • It cannot have an implementation, since it is up to the successors to determine its behavior.
0
source

1) Is it really necessary to define a method as virtual if it does not have an implementation? Of course, can it just be overwritten in a subclass without using virtual and overrides?

You can use abstract methods that do not have a body, but if you exit this class, you must override this method. All abstact methods must be overridden in the child class.

2) If (1) is incorrect, I understand correctly that each virtual method must be redefined in a subclass using it ....

No, instead, you can use the virtual to implement inside it, but not make overriding in the child class mandatory. From this perspective, you get more flexibility.

Usually they use abstract to create strict restrictions for children, therefore, each child derived from it must implement the specified member of the base class.

0
source

All Articles