有一种方法可以实现你想要的--隐藏你不想看到的成员--但是让它自动应用,而不需要其他人在使用自定义界面方面进行合作。你可以通过重新引入所有你不想看到的成员,并给它们打上属性标签来实现。
这就是Windows Forms在某些情况下所做的事情,例如,基类属性对于特定的派生类没有意义。例如,Control有一个Text属性,但是在TabControl上,Text属性是无意义的。因此,TabControl覆盖了Text属性,并添加了属性覆盖的属性,说明“顺便说一下,在属性网格或Intellisense中不要显示我的Text属性。”属性仍然存在,但由于你从未看到它,它不会妨碍你。
如果你为成员(属性或方法)添加[EditorBrowsable(EditorBrowsableState.Never)]属性,则Intellisense将不再在其代码完成列表中显示该成员。如果我正确理解你的问题,这是你试图实现的重要事情:使应用程序代码难以意外地使用该成员。
对于属性,你可能还想添加[Browsable(false)]来隐藏属性从属性网格中,以及[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]以防止设计器将属性值写入.designer.cs文件。
这将使意外使用方法/属性变得非常困难。但是它们仍然不能保证。如果你需要保证,那么再加上一个[Obsolete]属性,并使用“将警告视为错误”进行构建--然后你就会被照顾到了。
如果基本成员是虚拟的,你可能想要覆盖它,并让你的覆盖只是调用基类。不要抛出异常,因为在正常情况下,基类将可能调用覆盖的成员。另一方面,如果基本成员不是虚拟的,那么你想使用“new”而不是“override”,你可以决定你的实现是否应该调用基类,或者只是抛出异常——没有人应该使用你重新引入的成员,所以这并不重要。
public class Widget : UserControl
{
[EditorBrowsable(EditorBrowsableState.Never)]
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Obsolete("The Text property does not apply to the Widget class.")]
public override string Text
{
get { return base.Text; }
set { base.Text = value; }
}
[EditorBrowsable(EditorBrowsableState.Never)]
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Obsolete("The CanFocus property does not apply to the Widget class.")]
public new bool CanFocus
{
get { throw new NotSupportedException(); }
}
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("The Hide method does not apply to the Widget class.")]
public new void Hide()
{
throw new NotSupportedException();
}
}
是的,这是相当多的工作,但你只需要每个成员、每个类做一次……嗯,对。但是,如果那些基类成员确实不适用于你的类,并且让它们存在会导致混乱,那么付出努力可能是值得的。