tags:

views:

202

answers:

7

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
+1  A: 

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
+5  A: 

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
+1  A: 

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.
Good example, but doesn't answer the question ;)
Metro Smurf
I am afraid but you're right about that.
Yves M.
+2  A: 

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
and the child class must be marked with override
Lucas B
@Lucas, exactly! I forgot that part.
Jerod Houghtelling
+12  A: 

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
Clear and just simply true.
Yves M.
+1  A: 

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
+2  A: 

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