9

Why is it necessary to use the new keyword when a method shall be hidden?

I have two classes:

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

public class Child : Parent
{
    public void Print()
    {
        Console.WriteLine("Child");
    }
}

Following code produces the given output:

Parent sut = new Child();
sut.Print();

Output: Parent

Child sut = new Child();
sut.Print();

Output: Child

I understand that this might be a problem if it the hiding was not intended but is there any other reason to use "new" (excepted avoding of warnings)?

Edit:

May be I was not clear. It is the same situation like:

public void foo(Parent p)
{
 p.Print();
}

which is called:

Child c = new Child;
foo (c);c
HerrLoesch
  • 1,023
  • 1
  • 13
  • 24
  • Did you mean `Parent sut = new Parent();`? – Humberto Aug 11 '10 at 13:10
  • 1
    @Humberto, no I think his example is sound. – Drew Noakes Aug 11 '10 at 13:16
  • possible duplicate of [why do we need the new keyword and why is the default behavior to hide and not override?](http://stackoverflow.com/questions/3117838/why-do-we-need-the-new-keyword-and-why-is-the-default-behavior-to-hide-and-not-ov) – H H Aug 11 '10 at 13:38

10 Answers10

15

No, but avoiding the warnings is incredibly important. The bugs caused by hiding can be insiduous, and after C++ (which just let you do it) both Java and C# chose two different ways to prevent them.

In Java, it is not possible to hide a base classes methods. The compiler will scream bloody murder if you try to do it.

In C#, there is the "new" keyword. It allows you to be explicit that you want to hide a method, and the compiler will warn you if you are not using it. Many developers make it a rule to have code compiler with no warnings because warnings can be a sign of bad code.

After all that, I have never had to use hiding. I would carefully consider why I was even considering using it, since its behavior is strange and almost never what I want.

Chris Pitman
  • 12,990
  • 3
  • 41
  • 56
5

If you are trying to use inheritance, you should make the method virtual in the base class, and override it in the child class.

The language designers have decided that when these keywords are not used, then method hiding should be explicitly done with the new keyword.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
3

Hiding is a bad idea. It makes code more confusing, and your intent is unclear. Programming languages are about expressing your intent to both the compiler and to other programmers. It is not clear without a new keyword whether your intent was to override or to hide, or if you were just ignorant of the base method.

There's also an element of foolproofing. "Shoot-self in foot. Are you sure? OK/Cancel".

The real question is why is hiding allowed in the first place. The problem with not allowing hiding, is that if you derive from a class in another assembly and add a Foo() method, and then that other assembly is updated to add a Foo() method, not allowing for hiding would break your code.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
3

Expanding on what Jon Hanna said...

The point of the warning is to tell you there is a name clash you might not be aware of. When you get the warning, you should do one of the following:

  1. Add virtual and override to polymorphically override the method from the base class
  2. Rename your method so its name no longer clashes with the method in the base class
  3. Add new to make clear your intention to hide the method

If you are extending or refining the behaviour of the method in the base class, use virtual and override, as others have said here.

If you have just written your method for the first time and discover you have a name clash you weren't aware of and it is not your intention to override, simply rename your method.

Option 1 or 2 is usually preferable. So when should you resort to option 3?

You use option 3 when the base class is not your code. You don't have the option to add a virtual to it. The typical scenario where you need the new goes like this:

You bought a third party library. It has an interesting class. You inherit from the class and add a new method that the original author didn't provide. So far, there's no hiding or overriding involved. Now you receive a version 2 of the library, with some new features you want to use. The authors have added a new method to their class, and its name clashes with a method you wrote in your derived class.

If your method is not used very much, you should rename it out of the way, option 2. But if there are many dependencies on your method, it would be very disruptive to rename it. So you add the new to say that there is no logical connection between your method and the one in the base class, even though they happen to have the same name. You don't have the ability to add a virtual to the method in the base class, nor do you want to do that. The two methods were designed by different developers and your method doesn't refine or extend the one in the base class - when you wrote yours, the one in the base class didn't exist.

So, it's rare that you need the new keyword, but when you do, it's important.

Concrete Gannet
  • 551
  • 4
  • 11
2

Because it makes it explicit that you are deliberately hiding the parent's method, rather than overriding it. There is a warning when you don't use new because your subclass's method may have a typo in it, and accidentally hiding a parent method can lead to some subtle bugs.

thecoop
  • 45,220
  • 19
  • 132
  • 189
2

You will have to use the new keyword if the method with the same signature in the base class isn't marked with abstract or virtual.

Jerod Houghtelling
  • 4,783
  • 1
  • 22
  • 30
1

Just mark the Parent's method virtual. Then you would do public override void Print() in your child class.

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

public class Child : Parent 
{ 
    public override void Print() 
    { 
        Console.WriteLine("Child"); 
    } 
} 

This way you get the real inheritance and you can call the parents Print() method from the Child by calling base.Print()

Yves M.
  • 3,330
  • 14
  • 12
1

Why is it necessary to use the new keyword when a method shall be hidden?

It is not necessary. The only function of new here is to suppress the warning.

The question could be: Why is it not an error to hide base class members?

H H
  • 263,252
  • 30
  • 330
  • 514
1

The answer to the addition to your question

May be I was not clear. It is the same situation like:

public void foo(Parent p) { p.Print(); } which is called:

Child c = new Child; foo (c);

The answer is the foo(c) will output Parent. The method that hides the parent method will not execute if you are calling the parent class as in the example. To get the output of Child you will need to use virtual and override as described in earlier answers.

btlog
  • 4,760
  • 2
  • 29
  • 38
0

You can check the details here why method hiding allowed and to the scope of it.

https://msdn.microsoft.com/en-us/library/aa691135(v=vs.71).aspx

Uneverno
  • 49
  • 3
  • 14