Is method hiding ever a good idea

前端 未结 8 1810
死守一世寂寞
死守一世寂寞 2020-12-01 09:29

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 hidin

相关标签:
8条回答
  • One time I've used it is in a custom winforms control. My custom control overrides the Text property, and I want to raise an event whenever it changes. The base Control class comes with a TextChanged event, however the base event has attributes slapped on it to prevent it from showing up in the designer or in intellisense. Since we are using the event in our custom control, this is undesirable, so we do the following:

        [Browsable(true)]
        [EditorBrowsable(EditorBrowsableState.Always)]
        public new event EventHandler TextChanged
        {
            add { base.TextChanged += value; }
            remove { base.TextChanged -= value; }
        }
    

    Event handlers will still get added to the same event regardless of the type of reference that is used to access it, but references of derived-type will have the TextChanged event show up in intellisense, and when our control is placed on a form in the designer, the TextChanged event will show up in the properties window.

    0 讨论(0)
  • 2020-12-01 09:36

    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.

    0 讨论(0)
  • 2020-12-01 09:38

    I had to resort to method hiding once. I was using a a 3rd party library which provided a method that was non-virtual (That's the key to the whole thing). It was a method that allocated an instance of something. But I needed to extend the functionality of that method.

    So I used the 'new' keyword to hide the base class implementation and provide my own in a derived class. How that doesn't mean I didn't call the base class method. In fact I did call the base-class method, but I did other stuff in my method too, and everything worked out alright in the end.

    So I'd say the reasons would be the following:

    1. A base class is in a 3rd party library that you have no control over.
    2. A base class has a non-virtual method that you need to override.
    3. Always pay special attention to extending the functionality not replacing it.
    4. And always use this a last resort when stuck.... :)

    My 2 cents...

    0 讨论(0)
  • 2020-12-01 09:42

    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.

    0 讨论(0)
  • 2020-12-01 09:43

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

    0 讨论(0)
  • 2020-12-01 09:45

    I recently had a case where the 'new' keyword was quite useful. I was writing unit tests for methods in a legacy code base and some of the methods in classes I was writing tests for had external dependencies hidden inside the methods. Including a mocking framework to solve the problem seemed unnecessary at the time, so instead of using a mocking framework I inherited the class I wanted to test inside the unit test class. However, the parent method was not virtual so it could not be overridden. My first solution was to just simply add the virtual keyword to the original method to allow it to be overridden and the tests worked great. Even though it worked, I don't think that adding virtual keywords to method signatures only because of the need to "mock" it in a unit test is a good design decision (but I might be wrong). Instead the usage of 'new' keyword in the child class enabled me to 'get rid of' the parent methods dependencies by hiding the original method with a method with static return values, thus writing fast unit tests for rest of the methods worked as well as when changing non-virtual methods to virtual methods.

    In general, I am not sure this technique can be considered good practice. However, using this kind of technique might be very useful when writing a test suite to ease refactoring when working with legacy code with many dependencies and does not have an automated test suite to start with. The tests can most likely be improved when the refactoring work is completed.

    EDIT: Because method hiding only occurs in the private inherited class it should not cause any confusion that might occur in other use cases.

    0 讨论(0)
提交回复
热议问题