C# - Keyword Usage Virtual+Override Vs. New

C# - Keyword usage virtual+override vs. new

The "new" keyword doesn't override, it signifies a new method that has nothing to do with the base class method.

public class Foo
{
public bool DoSomething() { return false; }
}

public class Bar : Foo
{
public new bool DoSomething() { return true; }
}

public class Test
{
public static void Main ()
{
Foo test = new Bar ();
Console.WriteLine (test.DoSomething ());
}
}

This prints false, if you used override it would have printed true.

(Base code taken from Joseph Daigle)

So, if you are doing real polymorphism you SHOULD ALWAYS OVERRIDE. The only place where you need to use "new" is when the method is not related in any way to the base class version.

What is the difference between the override and new keywords in C#?

The following page summarizes your question very nicely.

Knowing When to Use Override and New Keywords

Summary

Override: When a method of a base class is overridden in a derived class, the version in the derived class is used, even if the calling code didn't "know" that the object was an instance of the derived class.

New: If you use the new keyword instead of override, the method in the derived class doesn't override the method in the base class, it merely hides it.

If you don't specify either new or overrides, the resulting output is the same as if you specified new, but you'll also get a compiler warning (as you may not be aware that you're hiding a method in the base class method, or indeed you may have wanted to override it, and merely forgot to include the keyword).

Override: used with virtual/abstract/override type of method in base class

New: when base class has not declared method as virtual/abstract/override

The difference between virtual, override, new and sealed override

The virtual keyword is used to modify a method, property, indexer or event declaration, and allow it to be overridden in a derived class. For example, this method can be overridden by any class that inherits it:
Use the new modifier to explicitly hide a member inherited from a base class. To hide an inherited member, declare it in the derived class using the same name, and modify it with the new modifier.

This is all to do with polymorphism. When a virtual method is called on a reference, the actual type of the object that the reference refers to is used to decide which method implementation to use. When a method of a base class is overridden in a derived class, the version in the derived class is used, even if the calling code didn't "know" that the object was an instance of the derived class. For instance:

public class Base
{
public virtual void SomeMethod()
{
}
}

public class Derived : Base
{
public override void SomeMethod()
{
}
}

...

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

will end up calling Derived.SomeMethod if that overrides Base.SomeMethod.

Now, if you use the new keyword instead of override, the method in the derived class doesn't override the method in the base class, it merely hides it. In that case, code like this:

public class Base
{
public virtual void SomeOtherMethod()
{
}
}

public class Derived : Base
{
public new void SomeOtherMethod()
{
}
}

...


Base b = new Derived();
Derived d = new Derived();
b.SomeOtherMethod();
d.SomeOtherMethod();

Will first call Base.SomeOtherMethod , then Derived.SomeOtherMethod . They're effectively two entirely separate methods which happen to have the same name, rather than the derived method overriding the base method.

If you don't specify either new or overrides, the resulting output is the same as if you specified new, but you'll also get a compiler warning (as you may not be aware that you're hiding a method in the base class method, or indeed you may have wanted to override it, and merely forgot to include the keyword).

An overriding property declaration may include the sealed modifier. Use of this modifier prevents a derived class from further overriding the property. The accessors of a sealed property are also sealed.

When to use new instead of override C#

The new keyword is the right way to go when you want to hide a base implementation and you don't care that you won't be able to call your method when treating your object polymorphically.

Let me clarify. Consider the following:

public class Base
{
public void DoSomething()
{
Console.WriteLine("Base");
}
}

public class Child : Base
{
public new void DoSomething()
{
Console.WriteLine("Child");
}
}

From time to time, it is beneficial to hide the base class' functionality in the child hence the use of the new keyword. The problem is that some developers do this blindly which will lead to the following side effect (hence the 'bugs' you mention):

Base instance = new Child();
instance.DoSomething(); // may expect "Child" but writes "Base"

Virtual and override

This is a good question.

You use the override keyword to override a virtual method because you can actually define a second virtual method in a derived class, with the same signature as the base classes virtual method, and this can be overridden as well.

This is the actual example from MSDN:

using System;
class A
{
public virtual void F() { Console.WriteLine("A.F"); }
}
class B: A
{
public override void F() { Console.WriteLine("B.F"); }
}
class C: B
{
new public virtual void F() { Console.WriteLine("C.F"); }
}
class D: C
{
public override void F() { Console.WriteLine("D.F"); }
}
class Test
{
static void Main() {
D d = new D();
A a = d;
B b = d;
C c = d;
a.F();
b.F();
c.F();
d.F();
}
}

yields:

B.F
B.F
D.F
D.F

because:

the C and D classes contain two virtual methods with the same
signature: The one introduced by A and the one introduced by C. The
method introduced by C hides the method inherited from A. Thus, the
override declaration in D overrides the method introduced by C, and it
is not possible for D to override the method introduced by A.

Difference between new and override

The override modifier may be used on
virtual methods and must be used on
abstract methods. This indicates for
the compiler to use the last defined
implementation of a method. Even if
the method is called on a reference to
the base class it will use the
implementation overriding it.

public class Base
{
public virtual void DoIt()
{
}
}

public class Derived : Base
{
public override void DoIt()
{
}
}

Base b = new Derived();
b.DoIt(); // Calls Derived.DoIt

will call Derived.DoIt if that overrides Base.DoIt.

The new modifier instructs the
compiler to use your child class implementation
instead of the parent class
implementation. Any code that is not
referencing your class but the parent
class will use the parent class
implementation.

public class Base
{
public virtual void DoIt()
{
}
}

public class Derived : Base
{
public new void DoIt()
{
}
}

Base b = new Derived();
Derived d = new Derived();

b.DoIt(); // Calls Base.DoIt
d.DoIt(); // Calls Derived.DoIt

Will first call Base.DoIt, then Derived.DoIt. They're effectively two entirely separate methods which happen to have the same name, rather than the derived method overriding the base method.

Source: Microsoft blog

Confused about override vs. new in C#

You've never actually overriden the Base version of Print(). You've only hidden it with a separate virtual method (named the same) in Der1.

When you use the new keyword on a method signature - you are telling the compiler that this is a method that happens to have the same name as a method of one of your base classes - but has no other relation. You can make this new method virtual (as you've done) but that's not the same as overriding the base class method.

In Der2 when you override Print you are actually overriding the 'new' version that you declared in Der1 - not the version is Base. Eric Lippert has an excellent answer to a slightly different question that may help you reason about how virtual methods are treated in the C# language.

In your example, when you call Print, you are calling it in the first case through a reference of type Base - so the hidden (but not overriden) version of Print is called. The other two calls are dispatched to Der1's implementation, because in this case, you've actually overriden the method.

You can read more about this in the MSDN documentation of new and override.

What you may have intended to do with Der1 (as you did with Der2) is to use the override keyword:

class Base 
{
public virtual void Print()
{
Console.WriteLine("Base");
}
}

class Der1 : Base
{
// omitting 'new' and using override here will override Base
public override void Print()
{
Console.WriteLine("Der1");
}
}

Override and New Keywords (C# Programming)

Override/Virtual and New actually solve two different problems and have two different uses.

Here is an example of virtual/override. Where the base class and the child class both return the exact same type (void).

public abstract class ServiceBase 
{
public virtual void BeginTran()
{
base.BeginTran();
}
}

public sealed class SearchService : ServiceBase
{
public override void BeginTran()
{
base.BeginTran();
}
}

However, notice in your example using new you have this :

public sealed class SearchService : ServiceBase 
{
public new SearchService BeginTran()
{
base.BeginTran();
return this;
}
}

Your return type is now SearchService, not void. Because you have changed the return type, you can't "Override" the method, you need to use the new keyword to return a different type. This is called method "hiding".

There is also other side effects to this. Essentially the two methods are not connected, so polymorphism can often completely break and do unexpected things.

I would personally say that method hiding, or using the new keyword is a direct contradiction of the Liskov Principle which says that types can be replaced by subtypes without altering the program. In your case, that would not be true if you change the return type. Bit more info on that here : https://dotnetcoretutorials.com/2019/10/20/solid-in-c-liskov-principle/

In 15+ years of C# experience, I have used the new keyword maybe a handful of times, and almost always when trying to override a library method and bastardize the code.



Related Topics



Leave a reply



Submit