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#和所有面向对象编程语言都是多年来建立在标准模式集之上的。“公共”的含义实际上是公共的,它应该无处不在。你不能有一个公共的地方,它可以成为私人的地方,尝试解决答案的接口,其他模式或内部关键字,但试图了解系统的设计