在 C# 中,
我从未遇到过隐藏方法是最佳选择的情况。是否存在方法隐藏是最佳选择的情况?
new
修饰符可用于隐藏基类方法而不覆盖基类方法。我从未遇到过隐藏方法是最佳选择的情况。是否存在方法隐藏是最佳选择的情况?
使用方法隐藏的情况很少,但有时确实非常有效。Eric Lippert在他的博客上发布了一个很好的例子:
interface IEnumerable<T> : IEnumerable {
new IEnumerator<T> GetEnumerator();
}
然而,我认为隐藏应该是例外,只有在必要时才应该使用。
我有时候为了方便调用者而使用它:
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; }
}
}
所以,当派生类保证被捕获的动物总是一只老鼠时,调用者就不必自己转换为 Mouse
类型。并且多态功能仍然存在。MouseTrap
强制转换回AnimalTrap
并放入不同类型的Animal
。 - Aaronaughtclass AnimalTrap<TAnimal> where TAnimal : Animal { ... }
呢?
如果您真的想要一个非泛型的动物陷阱,您可以像这样继承泛型类:class AnimalTrap : AnimalTrap<Animal> { ... }
。 - Nulliuspublic class MyControl : Control
{
[Browsable(false)]
public new Padding Padding
{
get { return base.Padding; }
set { base.Padding = value; }
}
}
在这种情况下,我们实际上是使用成员隐藏来隐藏成员 - 从设计者的角度看不到。TypeDescriptor
或 TypeConverter
。该方法的弱点(或优点,取决于您的需求)是它是选择加入的,而成员隐藏版本是选择退出的。 - AaronaughtDbCommand
和SqlCommand
这样的东西;具体类型(SqlCommand
等)通常会进行大量方法隐藏,以使属性/方法的返回类型显示正确的实现类型。这是因为相关对象本身具有附加的(特定于实现的)功能,调用者不想每次调用都进行强制转换。如果你只是基类的使用者,而新版本的基类突然发布了一个与你在派生类中已经实现的方法具有完全相同签名的方法,则需要能够隐藏基类方法,并使用 new
来明确表明你正在隐藏基类方法。
DerivedFoo
有一个DoSomething(double)
方法,并且Foo
的未来版本添加了一个DoSomething(int)
方法,则代码可能会期望derivedThing.DoSomething(4)
调用派生类方法,但是基类中的新重载可以被认为是“更好的匹配”。并非所有这个问题的变化都会导致编译器诊断。 - supercat我曾经不得不使用方法隐藏。我正在使用一个第三方库,该库提供了一个非虚拟方法(这是整个问题的关键)。它是一个分配某些东西实例的方法。但是我需要扩展该方法的功能。
所以我使用了 'new' 关键字来隐藏基类实现,并在派生类中提供自己的实现。但这并不意味着我没有调用基类方法。事实上,我确实调用了基类方法,但我在我的方法中做了其他的事情,在最后一切都很好。
因此,我认为原因如下:
仅供参考...
我曾经在自定义的winforms控件中使用过它。我的自定义控件覆盖了Text
属性,每当它改变时,我想触发一个事件。基本的Control
类带有一个TextChanged
事件,但是这个基本事件上有一些属性,以防止它出现在设计器或者智能感知中。由于我们在自定义控件中使用该事件,这是不可取的,因此我们采取以下措施:
[Browsable(true)]
[EditorBrowsable(EditorBrowsableState.Always)]
public new event EventHandler TextChanged
{
add { base.TextChanged += value; }
remove { base.TextChanged -= value; }
}