C# and method hiding
Asked Answered
R

9

6

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

Readus answered 23/7, 2009 at 7:20 Comment(1)
btw, method hiding is not same as method overriding.Botelho
C
10

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.

Ciaracibber answered 23/7, 2009 at 7:28 Comment(4)
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.Yak
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?Ciaracibber
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.Anvers
@Jon: Woops - I missed his mention of overriding. You have indeed answered his question(s).Yak
Y
3

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#.

Yak answered 23/7, 2009 at 7:29 Comment(3)
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.Ciaracibber
In particular, see download.microsoft.com/download/a/9/e/… section 10.5.Ciaracibber
@Jon Skeet: I noticed the absence of a link to the .NET 1.1 page on the new keyword, and rather assumed it...Yak
B
1

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)

Botelho answered 23/7, 2009 at 7:21 Comment(0)
O
1

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'

UPDATE: 14/5/11

I moved my blog, so I'm updating any old links

Osier answered 23/7, 2009 at 7:25 Comment(0)
K
1

The only difference between using "new" and "not using new" is that, you will get a compiler warning when you don't use the "new" keyword, to alert the developer of any inadvertent method hiding that is happening. At the following URL you can also find an excellent video explaining method hiding and the difference between using "new" and "not using new".

Krieger answered 12/6, 2012 at 21:16 Comment(0)
P
0

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.

Pigweed answered 23/7, 2009 at 7:24 Comment(6)
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.Osier
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.Pigweed
Good programmers check warnings so this means the people who care will benefit from it.Pigweed
And the people who don't care will wonder where their bugs are. :)Osier
@Spence, can you explain this 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. with ref and out.Machicolation
It's to do with inheritance. If you use the keyword new, you are explicitly stating that if I declare this method but cast my object to a parent type, this method will not be called. As opposed to a virtual method that was overriden which would then be called if you did. Ref and Out are the same, in that you have to explicitly state "You give me an object ref/boxed primitive and I might change it (REF) vs. give me a place holder and I will give you a new object with a ref stored in the variable (OUT).Pigweed
B
0

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.

Brine answered 23/7, 2009 at 7:28 Comment(0)
D
0

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.

Datha answered 23/7, 2009 at 7:28 Comment(0)
R
0

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!

Readus answered 23/7, 2009 at 8:8 Comment(1)
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.Ciaracibber

© 2022 - 2024 — McMap. All rights reserved.