c#对dervied类隐藏基类的一些属性
我想知道是否可以对派生类隐藏基类属性: 例如:c#对dervied类隐藏基类的一些属性,c#,.net,inheritance,properties,C#,.net,Inheritance,Properties,我想知道是否可以对派生类隐藏基类属性: 例如: class BaseDocument { public string DocPath{get; set;} public string DocContent{get; set;} } class DerviedDocument: BaseDocument { //this class should not get the DocContent property
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”关键字,但这似乎也不能解决问题
我理解这会“破坏”继承,但我想这种情况应该经常出现,孩子需要从父母那里获得除一个或两个属性以外的所有其他属性
如何才能优雅地处理这些场景?就这样做吧
class BaseDocument
{
public DocPath{get; set;}
public virtual DocContent{get; set;}
}
class DerviedDocument: BaseDocument
{
public override DocContent
{
get { return null; }
set { }
}
}
或
就这么做吧
class BaseDocument
{
public DocPath{get; set;}
public virtual DocContent{get; set;}
}
class DerviedDocument: BaseDocument
{
public override DocContent
{
get { return null; }
set { }
}
}
或
我不相信有一个好的(或任何)方法来做到这一点。您可能必须打破层次结构,或者您可以从BaseDocument中删除DocContent属性,然后从BaseDocument派生两个独立的类,一个是您当前的派生文档,另一个是具有DocContent属性的类。我认为没有好的(或任何)方法可以做到这一点。您可能必须打破层次结构,或者您可以从BaseDocument中删除DocContent属性,然后从BaseDocument派生两个独立的类,一个是您当前的DerivedDocument,另一个是DocContent属性。我不确定继承是否是解决此问题的方法。是的,你可以通过使用黑客破解它,但我认为设计应该重新思考。一种可能的办法:
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
}
}
基本上,使用组合而不是继承,并将程序应用于接口,而不是实现。我不确定继承是否是实现的方法。是的,你可以通过使用黑客破解它,但我认为设计应该重新思考。一种可能的办法:
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
}
}
基本上,使用组合而不是继承,将程序编写到接口,而不是实现。听起来你想故意违反Liskov替换原则。如果子类不具备传统的继承语义,为什么还要费心子类化呢?只需创建一个单独的类。听起来你想故意违反Liskov替换原则。如果子类不具备传统的继承语义,为什么还要费心子类化呢?只需创建一个单独的类。如果您不介意在不同的程序集/项目中使用BaseDocument和DerivedDocument,则可以轻松地完成此操作
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) ;
}
}
将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对该程序集可见。(然而,在我看来,这是一个难题,尽管在某些情况下非常方便。)如果您不介意在不同的程序集/项目中使用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对该程序集可见。(然而,在我看来,这是一个难题,尽管在某些情况下非常方便。)反应迟钝,但有几种方法可以做到这一点 最漂亮:将
Base
类放在一个单独的程序集中,并将属性DocContent
标记为internal
,而不是public
:
class BaseDocument
{
public string DocPath{get; set;}
internal string DocContent{get; set;} //won't be visible outside the assembly
}
或者使用属性
在源编辑器中隐藏属性:
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
}
}
一个迟来的反应,但有几种方法可以做到这一点 最漂亮:将
Base
类放在一个单独的程序集中,并将属性DocContent
标记为internal
,而不是public
:
class BaseDocument
{
public string DocPath{get; set;}
internal string DocContent{get; set;} //won't be visible outside the assembly
}
或者使用属性
在源编辑器中隐藏属性:
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
}
}
我有一个与问题类似的现有场景。而且,我只是好奇地想知道!就像其他人提到的。。。如果是这样的话,你不应该从基础上推导。派生类应该完全支持基类接口。如果我的程序与CBase一起工作,它的行为应该是不变的,即使我为CBase提供了任何CDerived——1表示无效问题。首先,C#和所有面向对象编程语言都是多年来建立在标准模式集之上的。“公共”的含义实际上是公共的,它应该无处不在。你不能有一个公共的地方,它可以成为私人的地方,尝试解决答案的接口,其他模式或内部关键字,但试图了解系统的设计