c#隐藏类的基类的一些属性

我想知道是否可以从派生类中隐藏基类属性:

例:

class BaseDocument { public string DocPath{get; set;} public string DocContent{get; set;} } class DerviedDocument: BaseDocument { //this class should not get the DocContent property public Test() { DerivedDocument d = new DerivedDocument(); d.//intellisense should only show me DocPath //I do not want this class to see the DocContent property } } 

我不能将DocContent属性设为私有,因为我想在其他地方实例化BaseDocument类并在那里使用该属性。 无论如何,这将扼杀财产的想法。

解决这个问题的一种方法是使用一个接口,比如IDoc,它暴露DocPath属性并使BaseDocument和DerivedDocument都实现接口。 这会打破他们的亲子关系。

我可以使用new和override关键字,但这不是正确的方法,因为孩子仍然“看到”该属性

我尝试在DocContent上使用’sealed’关键字,但这似乎也没有解决问题。

我知道它“打破”inheritance,但我想这种情况应该经常出现在一个孩子需要从父母那里获得其他所有东西但只有一两个属性的情况。

如何优雅地处理这些场景?

我不确定inheritance是否可以去这里。 是的,您可以使用EditorBrowsableAttribute来解决它,但我认为应该重新考虑设计。 一种可能的方法:

 public interface IDoc { DocPath{get;set;} } class BaseDocument : IDoc { public DocPath{get; set;} public DocContent{get; set;} } class DerviedDocument { public DerivedDocument(IDoc doc) { this.Doc = doc; } public IDoc Doc{get;set;} public Test() { DerivedDocument d = new DerivedDocument(new BaseDocument()); d.//here you will only see d.IDoc which only exposes DocPath } } 

基本上,使用组合而不是inheritance,并编程到接口,而不是实现。

如果您不介意在不同的程序集/项目中使用BaseDocument和DerivedDocument,则可以轻松完成。

使DocContent成为内部。 它将与BaseDocument在同一项目中的所有内容都可见,但DerivedDocument不会显示它,因为它位于不同的项目中。 当然,您需要公开BaseDocument(现在您将其作为默认设置,内部)。

在第一个项目中:

 public class BaseDocument { public string DocPath {get; set;} internal string DocContent {get; set;} } 

在第一个引用第一个项目:

 class DerivedDocument : FirstProject.BaseDocument { public Test() { DerivedDocument d = new DerivedDocument(); d. //intellisense shows DocPath, but not DocContent } } 

该解决方案具有不成为污泥的优点。 您仍然可以在BaseDocument的项目中使用BaseDocument的DocContent属性。 如果需要在另一个项目中使用DocContent(与项目DerivedDocument不同),可以使用InternalsVisibleTo属性使DocContent对该程序集可见。 (但是,在我看来,这一种kludge,虽然在某些情况下非常方便。)

听起来你想故意违反Liskov替代原则。 如果它不具备传统的inheritance语义,为什么还要继续使用子类? 只做一个单独的课程。

 interface IBaseDocument { string DocPath { get ; set ; } string DocContent { get ; set ; } } class BaseDocument : IBaseDocument { public string DocPath { get ; set ; } // implement normally private string MyDocContent ; // use this in BaseDocument string IBaseDocument.DocContent // implement explicitly { get { return MyDocContent ; } set { MyDocContent = value ; } } } class DerviedDocument : BaseDocument { public void Test () { // error: The name 'DocContent' does not exist in the current context Console.WriteLine (DocContent) ; } } 

我不相信有这么好的(或任何)方法。 您可能必须中断层次结构,或者可以从BaseDocument中删除DocContent属性,然后从BaseDocument派生两个sepearate类,一个是您当前的DerivedDocument,另一个是具有DocContent属性。

后期反应,但有几种方法可以做到这一点。

最漂亮:将Base类放在单独的程序DocContent ,并将属性DocContent标记为internal而不是public

 class BaseDocument { public string DocPath{get; set;} internal string DocContent{get; set;} //won't be visible outside the assembly } 

或者使用attributes从源编辑器中隐藏属性:

 class BaseDocument { public string DocPath{get; set;} public string DocContent{get; set;} } class DerviedDocument: BaseDocument { //this class should not get the DocContent property [Browsable(false), EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public new string DocContent{ get; set; } public Test() { DerivedDocument d = new DerivedDocument(); d.//intellisense will only show me DocPath //I do not want this class to see the DocContent property } } 

就这样做吧。

 class BaseDocument { public DocPath{get; set;} public virtual DocContent{get; set;} } class DerviedDocument: BaseDocument { public override DocContent { get { return null; } set { } } } 

要么

 public override DocContent { get { throw new NotImplementedException("Do not use this property!"); } set { throw new NotImplementedException("Do not use this property!"); } }