tags:

views:

365

answers:

5

In C# the new modifier can be used to hide a base class method without overriding the base class method.

I've never encountered a situation where hiding a method was the best choice available. Are there any situations where method hiding is the best choice?

+13  A: 

There are rare, but very good, reasons to use method hiding. Eric Lippert posted a great example on his blog:

interface IEnumerable<T> : IEnumerable { 
  new IEnumerator<T> GetEnumerator(); 
}

However, I think hiding should be the exception, and only used sparingly.

Reed Copsey
+3  A: 

Yes, if you are, for example, just a consumer of a base class and a new version of base class is published that all of a sudden has the method with the exact same signature as one of the methods that you already implemented in your derived class, you need to be able to hide the base class method and you use new to make it clear that you are hiding the base class method...

kzen
This is the one legitimate use I was aware of when I asked the question. I would go to great lengths to change method names and avoid the need for new. If I could not change the name, I would probably introduce a method with a new name and mark the conflicting method as deprecated at the same time as adding new to hide the base method.
ScottS
+9  A: 

It's often a good choice when you're creating custom controls, and want to prevent certain properties from appearing in the designer. Sometimes the properties aren't overridable, but the designer doesn't care about that, it only cares whether or not the lowest-level public property has the [Browsable] attribute.

For example, let's say that your control doesn't support padding. The Control.Padding property isn't overridable. But you also know that nothing bad is going to happen if somebody sets the padding, it's just that the property doesn't do anything, so you don't want your users to see it in the designer and think that it actually works. So, hide it:

public class MyControl : Control
{
    [Browsable(false)]
    public new Padding Padding
    {
        get { return base.Padding; }
        set { base.Padding = value; }
    }
}

In this case, we're literally using member hiding to hide the member - from the designer.

As an aside, I'm aware that there are other means of achieving this goal - this is just one possible option.

Aaronaught
I've been using this method to hide a property. What are these other means that you talk about? do you have a link?
Pierre-Alain Vigeant
@Pierre: You can also implement your own `TypeDescriptor` or `TypeConverter`. The weakness (or strength, depending on your requirements) of that method is that it's opt-in, whereas the member-hiding version is opt-out.
Aaronaught
Nice example +1
ajdams
+6  A: 

I tend to use it sometimes for convenience for callers, something like:

abstract public class Animal { }

public class Mouse : Animal { }



public class AnimalTrap
{
    public Animal TrappedAnimal { get; }
}

public class MouseTrap : AnimalTrap
{
    new public Mouse TrappedAnimal
    {
        get { return (Mouse)base.TrappedAnimal; }
    }
}

So the caller doesn't have to cast to Mouse themselves when the derived class guarantees the trapped animal will always be a mouse. And polymorphic functionality stays intact.

herzmeister der welten
+1 This is a nice clear example of return type covariance that Eric Lippert's blog post talks about. I had to stop and think in order to grok the IEnumerable<T> example, but this is straight forward.
ScottS
@ScottS: This is a good example of method hiding but it has nothing to do with return type covariance. In fact, there's no type safety guarantee here, a caller could cast `MouseTrap` back to `AnimalTrap` and put a different type of `Animal` in there.
Aaronaught
@Aaronaught, my understanding of return type covariance is simply changing a methods return type in a derived class. Am I missing something? This emulation of return type co-variance does require that the new return type can be cast to be compatible with it's parent(s) return type(s). Presumably MouseTrap has some logic that only allows it to trap mice. Then you can call AnimalTrap.TrappedAnimal on an instance of MouseTrap and you will safely get a Mouse.
ScottS
@ScottS: The concept of covariant return types applies to overridden methods - if you can override the base method, but return a more specific type than the base class, that means the language allows covariant return types. (Incidentally, C# doesn't, although it supports other types of co/contra-variance.) Method hiding isn't covariance - you could have a method declared with `new` return any type at all.
Aaronaught
And @ScottS - it's not "safe" either, the base `AnimalTrap` is not guaranteed to contain an instance of `Mouse`, so this could quite possibly throw an `InvalidCastException` under the wrong circumstances. The method is just there for convenience, so callers who already know that it's a `MouseTrap` don't have to keep writing casts.
Aaronaught
@Aaronaught, I agree this is not true return type co-variance, but is as close of facsimile to return type co-variance that c# supports. If you need return type co-variance in c# this appears to be the best technique to apply. As for the invalid cast, I was assuming that the omitted code that traps animals would ensure that mouse traps only trap mice, thus guaranteeing the cast will not be a problem.
ScottS
+2  A: 

The most common example I can think of here is things like DbCommand vs SqlCommand; the concrete types (SqlCommand etc) generally do a lot of method hiding to make the return types of properties / methods display the correct implementation type. This is because the related objects themselves have additional (implementation-specific) features, and the caller doesn't want to have to cast every time they call do anything.

Marc Gravell