views:

382

answers:

8

Per MSDN, the "new" keyword when used for method hiding only suppresses a warning.

http://msdn.microsoft.com/en-us/library/435f1dw2.aspx

Do I really need this "new" keyword to perform method hiding? If I have a child class that has the same method name but doesn't explicitly state that it is overriding, isn't that the same thing essentially, I just get a warning? Please tell me if my understanding is correct. Thanks

A: 

It's part of C#, just like ref and out. The idea is to warn you that your API is overriding a method which could affect code that relies on sub/superclasses of your class.

Placing the new keyword forces you to think about whether that is really what you intended to do or not, just like requiring ref or out so that you have to think about the contract your code is providing.

Spence
The problem is that "new" is not "required". You only get a compiler warning if you miss it. If you miss "ref" or "out" when calling a method with it in the parameters you'll get a compiler error.
Colin Mackay
They were trying not to break code. ref and out were thought of right from the start and thus they are actually enforced as such.
Spence
Good programmers check warnings so this means the people who care will benefit from it.
Spence
And the people who don't care will wonder where their bugs are. :)
Colin Mackay
+1  A: 

Method hiding is not the same as overriding. Do not use it where overriding should be your choice as they work differently.

I wrote about this some time ago, you might want to read Method hiding or overriding - or the difference between new and virtual for more details.

Method hiding should be discouraged because it changes the semantics of a class. The functionality changes depending on if you have a reference to the base, or the actual class. That's the main reason there is a compiler warning about it. It can do unexpected things if the caller is not aware that method hiding is in use.

ADDITIONAL

Based on updates to the question. Method Hiding does not require the keyword new, although you should make it explicit and use the keyword if that is what you are doing. It removes the compiler warning and alerts other developers (or yourself 6 months down the line) what your intention was.

I still wouldn't recommend method hiding, tho'

Colin Mackay
A: 

As far as I know, the only difference is the one you suggest: new hides the warning. I tried out the following code:

class Base
{
    public void Test(){}
}

class ChildA : Base
{
    public void Test(){}
}


class ChildB : Base
{
    public new void Test(){}
}

The test method for both classes look identical in IL:

.method public hidebysig instance void  Test() cil managed
{
  // Code size       1 (0x1)
  .maxstack  8
  IL_0000:  ret
} // end of method ChildA::Test

.method public hidebysig instance void  Test() cil managed
{
  // Code size       1 (0x1)
  .maxstack  8
  IL_0000:  ret
} // end of method ChildB::Test

The compiler issued a warning for Test in ClassA, but not in ClassB. But as other answers has stated; don't confuse the concepts of method hiding and method overriding; not the same thing.

Fredrik Mörk
+5  A: 

You get method hiding whether or not you specify "new", but it's not the same as overriding. Here's an example where they're different:

using System;

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

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

class Derived : Base
{
    public override void OverrideMe()
    {
        Console.WriteLine("Derived.OverrideMe");
    }

    public new void HideMe()
    {
        Console.WriteLine("Derived.HideMe");
    }
}

class Test
{
    static void Main()
    {
        Base x = new Derived();
        x.OverrideMe();
        x.HideMe();
    }
}

The output is:

Derived.OverrideMe
Base.HideMe

Even though the base HideMe method is virtual, it isn't overridden in Derived, it's just hidden - so the method is still bound to the virtual method in Base, and that's what gets executed.

Member hiding is generally a bad idea, making the code harder to understand. The fact that it's available is beneficial in terms of versioning, however - it means adding a method to a base class doesn't potentially let derived classes override it unintentionally, and they can keep working as before. That's why you get the warning.

Jon Skeet
I'm not sure you've answered the question the OP was asking... though it's useful clarification in case he wasn't sure anyway, I guess. Member hiding *can* be quite useful in certain situations; it's just overused by newbies.
Noldorin
Well, I said: "You get method hiding whether or not you specify 'new'" which answers his first question, and I answered that hiding is not the same thing as overriding, which answers his second question. Which question do you think I didn't answer?
Jon Skeet
I think the biggest thing about using 'new' to hide it, is that it CLARIFIES your intentions, if you don't then someone (or even yourself) can come along later and think that maybe it was meant to be overloaded, or they start using the base class, and don't understand why the function suddenly changes its functionality.
Grant Peters
@Jon: Woops - I missed his mention of overriding. You have indeed answered his question(s).
Noldorin
A: 

The use of new is when you want a function of the same name, but you don't want to override. It breaks the virtual dispatch chain.

This might happen when somebody adds a function to a base class that has the same name as your derived class function.

Aneef
+1  A: 

The new keyword should always be used when hiding (shadowing) methods. Although technically it does not make a difference to functionality, as you correctly point out, it is strongly recommended.

The prescence of the keyword not only indicates clearly to the reader of the code that you are explicitly hiding a method of the same name in the base class, but also its usage is part of the official (MSDN) C# guidelines, quite possibly because its usage may be required in the future.

The reason that the current compiler only gives you a warning (rather than an error) when you omit the keyword is purely for reasons of backward compatibility. C# 1.0 does not support the new keyword for hiding members of classes, as MSDN suggests, and method (generally member) hiding was performed then automatically. I suspect MS will try to maintain backward compatibility in this respect, but it's certainly not guaranteed in future versions of C#.

Noldorin
Um, I'm pretty sure C# has *always* supported "new" for member hiding, right since 1.0. "new" is present for backward compatibility with previous versions of base classes, not backward compatibility with previous versions of the language.
Jon Skeet
In particular, see http://download.microsoft.com/download/a/9/e/a9e229b9-fee5-4c3e-8476-917dee385062/CSharp%20Language%20Specification%20v1.0.doc section 10.5.
Jon Skeet
@Jon Skeet: I noticed the absence of a link to the .NET 1.1 page on the `new` keyword, and rather assumed it...
Noldorin
+1  A: 

Use of new keyword while hiding a method is to "make the intent of the programmer clear". This avoids accidental hidings by the programmers.

If the new keyword is not present then the compiler issues a warning and treats it as if it was present.

You can read more about it Versioning with the Override and New Keywords (C# Programming Guide)

chikak
A: 

Thanks guys. I am aware of the differences between hiding and overriding, I was just curious if there was a functionality difference between using "new" and not using "new" for hiding. According to all of your answers, it seems not although as someone had raised a good point in that it makes for cleaner code and it may be necessary in the future. THanks again Folks!

If you're aware of the difference between hiding and overriding, you may wish to edit your qusetion: "If I have a child class that has the same method name but doesn't explicitly state that it is overriding, isn't that the same thing essentially, I just get a warning?" implies that you believe it's the same as if you *did* override explicitly, when it's not.
Jon Skeet