方法隐藏是一个好主意

Sco*_*ttS 34 c# oop

在C#中,new修饰符可用于隐藏基类方法而不覆盖基类方法.

我从来没有遇到过隐藏方法是最好的选择的情况.是否存在方法隐藏是最佳选择的情况?

Ree*_*sey 19

使用方法隐藏的原因很少但非常好.Eric Lippert 在他的博客上发布了一个很好的例子:

interface IEnumerable<T> : IEnumerable { 
  new IEnumerator<T> GetEnumerator(); 
}
Run Code Online (Sandbox Code Playgroud)

但是,我认为隐藏应该是例外,并且只是谨慎使用.

  • 是的,但Eric Lippert后来评论说:"当然,如果C#有方法返回类型协方差,那么这不一定是一种新方法.这给了我们一个更好的理由隐藏方法;它允许类似返回类型协方差的东西用一种没有这种功能的语言." .所以问题是:为什么C#不支持返回类型协方差? (2认同)

her*_*ter 16

为了方便呼叫者,我倾向于使用它,例如:

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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,Mouse当派生类保证被困动物永远是鼠标时,调用者不必强制转换为自己.多态功能保持不变.

  • +1这是Eric Lippert的博客文章谈到的返回类型协方差的一个很好的明显例子.我不得不停下来思考,以便了解IEnumerable <T>示例,但这很简单. (2认同)
  • @ScottS:这是方法隐藏的一个很好的例子,但与返回类型的协方差无关。实际上,这里没有类型安全保证,调用者可以将“ MouseTrap”转换回“ AnimalTrap”并在其中放置不同类型的“ Animal”。 (2认同)

Aar*_*ght 14

当您创建自定义控件时,它通常是一个不错的选择,并且希望阻止某些属性出现在设计器中.有时属性不会被覆盖,但设计者并不关心它,它只关心最低级别的公共属性是否具有该[Browsable]属性.

例如,假设您的控件不支持填充.该Control.Padding属性是不可重写.但是你也知道,如果有人设置了填充,就不会发生任何不好的事情,只是该属性没有任何事情,所以你不希望你的用户在设计师中看到它并认为它确实有效.所以,隐藏它:

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

在这种情况下,我们实际上使用成员隐藏来隐藏成员 - 来自设计师.

顺便说一句,我知道还有其他方法可以实现这一目标 - 这只是一个可能的选择.


Mar*_*ell 6

我能想到的最常见的例子是DbCommandvs SqlCommand; 具体类型(SqlCommand等)通常会做很多方法隐藏,以使返回类型的属性/方法显示正确的实现类型.这是因为相关对象本身具有附加的(特定于实现的)特征,并且调用者不希望每次调用时都必须进行转换.