Ahm*_*gdy 43 c# inheritance properties base-class
如果我有以下代码示例:
public class ClassBase
{
public int ID { get; set; }
public string Name { get; set; }
}
public class ClassA : ClassBase
{
public int JustNumber { get; set; }
public ClassA()
{
this.ID = 0;
this.Name = string.Empty;
this.JustNumber = string.Empty;
}
}
Run Code Online (Sandbox Code Playgroud)
如何在Name
不修改的情况下隐藏属性(不显示为ClassA成员)ClassBase
?
Ben*_*ter 62
我闻到了代码味道.我认为,如果要实现该基类的所有功能,则只应继承基类.你正在做的事情并不能真正代表面向对象的原则.因此,如果你想从你的基础继承,你应该实现Name,否则你的继承是错误的.你的A类应该是你的基类,你的当前基类应该继承自A,如果这是你想要的,而不是相反.
但是,不要偏离直接问题太远.如果你确实想要蔑视"规则",并希望继续沿着你所选择的道路前进 - 这就是你如何去做的:
惯例是实现属性,但在调用该属性时抛出NotImplementedException - 尽管如此,我也不喜欢它.但这是我个人的意见,并没有改变这个惯例仍然存在的事实.
如果您试图废弃该属性(并且它在基类中声明为虚拟),那么您可以使用它上面的Obsolete属性:
[Obsolete("This property has been deprecated and should no longer be used.", true)]
public override string Name
{
get
{
return base.Name;
}
set
{
base.Name = value;
}
}
Run Code Online (Sandbox Code Playgroud)
(编辑:正如Brian在评论中指出的那样,如果某人引用了Name属性,该属性的第二个参数将导致编译器错误,因此即使您已在派生类中实现它,他们也无法使用它. )
或者正如我提到的那样使用NotImplementedException:
public override string Name
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果该属性未声明为虚拟,则可以使用new关键字替换它:
public new string Name
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
您仍然可以像覆盖方法一样使用Obsolete属性,或者您可以抛出NotImplementedException,无论您选择哪个.我可能会用:
[Obsolete("Don't use this", true)]
public override string Name { get; set; }
Run Code Online (Sandbox Code Playgroud)
要么:
[Obsolete("Don't use this", true)]
public new string Name { get; set; }
Run Code Online (Sandbox Code Playgroud)
取决于它是否在基类中声明为虚拟.
Rya*_*ndy 33
虽然从技术上讲,该属性不会被隐藏,但强烈反对使用它的一种方法是将属性放在其上,如下所示:
[Browsable(false)]
[Bindable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[EditorBrowsable(EditorBrowsableState.Never)]
Run Code Online (Sandbox Code Playgroud)
这就是System.Windows.Forms为具有不适合的属性的控件所做的事情.该文本属性,例如,是在控制,但它不会使每个继承自Control类的感觉.所以在MonthCalendar中,例如,它看起来像这样(每个Reflector):
[Browsable(false),
EditorBrowsable(EditorBrowsableState.Never),
Bindable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Text {
get { return base.Text; }
set { base.Text = value; }
}
Run Code Online (Sandbox Code Playgroud)
可浏览表示该成员是否显示在"属性"窗口中. EditorBrowsable指示它是否显示在Intellisense下拉列表中.如果将EditorBrowsable设置为false,您仍然可以键入该属性,并且它仍然可以构建,但是您可以使用它并不明显.
CCo*_*ron 24
只是隐藏它
public class ClassBase
{
public int ID { get; set; }
public string Name { get; set; }
}
public class ClassA : ClassBase
{
public int JustNumber { get; set; }
private new string Name { get { return base.Name; } set { base.Name = value; } }
public ClassA()
{
this.ID = 0;
this.Name = string.Empty;
this.JustNumber = 0;
}
}
Run Code Online (Sandbox Code Playgroud)
注意:Name仍然是ClassBase的公共成员,考虑到不更改基类的约束,没有办法阻止它.
为什么在不必要时强制继承?我认为执行此操作的正确方法是执行has-a而不是is-a。
public class ClassBase
{
public int ID { get; set; }
public string Name { get; set; }
}
public class ClassA
{
private ClassBase _base;
public int ID { get { return this._base.ID; } }
public string JustNumber { get; set; }
public ClassA()
{
this._base = new ClassBase();
this._base.ID = 0;
this._base.Name = string.Empty;
this.JustNumber = string.Empty;
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
我不认为\xe2\x80\x99t 认为很多在这里回复的人根本理解继承。需要从基类继承并隐藏其曾经公共的 var\xe2\x80\x99s 和函数。例如,假设您有一个基本发动机,并且您想要制造一个增压的新发动机。好吧,您将使用 99% 的引擎,但您将对其功能进行一些调整以使其运行得更好,但仍然有一些功能应该只向所做的修改显示,而不是向最终用户显示。因为我们都知道 MS 推出的每个类都不需要任何修改。
\n\n除了使用新功能来简单地覆盖功能之外,它也是 Microsoft 在其无限 wis\xe2\x80\xa6 中所做的事情之一。哦,我的意思是错误认为不再值得的工具。
\n\n现在实现这一点的最佳方法是多级继承。
\n\npublic class classA \n{\n}\n\npublic class B : A \n{} \n\npublic class C : B \n{} \n
Run Code Online (Sandbox Code Playgroud)\n\nB 类完成您的所有工作,C 类公开您需要公开的内容。
\n