14

The C# language specification says that if I inherit a class, and the base class and derived class have the same named member with the same signature, then I have to use the new keyword to hide the base class member (There is another way by using virtual and override keyword in base and derived class member).

But in practice I found that the derived class auto hides the derived member if it has the same named member. So what is the main benefit and problem new keyword in same named derived class member?

Graham Clark
  • 12,886
  • 8
  • 50
  • 82
Md Kamruzzaman Sarker
  • 2,387
  • 3
  • 22
  • 38

3 Answers3

28

New is not required, as you note. It is optional, and if you do not use it, you get a warning. You are entirely correct to note that this is at first glance a strange design decision.

The purpose of this design decision is to help mitigate a class of problems known as the "Brittle Base Class" problems. Here's a version of that problem:

Foo Corporation creates a class Frobber and ships it in Foo.DLL version 1.0:

namespace FooCorp
{
  public class Frobber
  {
    public void Frobnicate() { ... }
    ...

Bar Corporation, who you work for, makes Blobbers. A Blobber can do everything that a Frobber can do, but in addition, it can Blobnicate too. So you decide to re-use the implementation of Frobnicate from FooCorp, and add some additional functionality:

namespace BarCorp
{
  public class Blobber : FooCorp.Frobber
  {
    public void Blobnicate() { ... }
    ...

Foo Corporation realizes that people like to Blobnicate, and they decide to ship Foo.DLL v2.0:

namespace FooCorp
{
  public class Frobber
  {
    public void Frobnicate() { ... }
    public void Blobnicate() { ... }
    ...

When you get a new version of Foo.DLL and recompile, you want to be told that you are now accidentally introducing a new method that shadows a base class method. That is possibly a dangerous thing to do; your class was written with the assumption that the base class was a Frobnicator, but apparently now it is a Blobnicator too! That fact could break your customers, who might accidentally call the base class version when they intended to call your derived class version.

We make "new" optional so that it is legal for you to shadow a base class method without changing your source code. If we made it illegal then FooCorp would have broken your build with their upgrade. But we make it a warning so that you know that you might be doing so accidentally. You can then examine the code carefully; if you decide that your implementation of Blobnicate is now redundant, you can remove it. If it is still good, you can mark it as "new" and eliminate the warning.

Make sense? This is one of the subtle features of C# that make it suitable for large scale multi-version component-oriented software.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
4

The benefit of using new is to make your intention clear.

However, unless you truly need to hide the member, it is generally preferrable to use virtual/override in order to use the member polymorphically. With hiding, the new member is only used via the reference of the derived class. If you are working via a base reference, you will continue to get the base behavior, and that might be unexpected.

class Foo 
{
     public void M() { Console.WriteLine("Foo"); }
}

class Bar : Foo
{
     public new void M() { Console.WriteLine("Bar"); }
}

Bar bar = new Bar(); 
bar.M(); // writes Bar
Foo foo = new Bar(); // still an instance of Bar
foo.M(); // writes Foo, does not use "new" method defined in Bar

If instead the method had been declared with virtual in Foo and override in Bar, then the method invocation would have been consistently "Bar" in either case.

Anthony Pegram
  • 123,721
  • 27
  • 225
  • 246
3

The new keyword allows you to be specific in your intent.

While the default behavior is to hide the base class' member without the new keyword, there's no way of telling if you really wanted to hide the member or if you actually wanted to override the member instead.

It's always better to be explicit. That way, the next developer will know exactly what you meant to do.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536