c # esconder a partir de classes dervied algumas propriedades de classe base

votos
0

Eu quero saber se é possível esconder uma propriedade classe base de uma classe derivada:

Exemplo:

    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
        }
    }

Eu não posso tornar a propriedade DocContent privada, porque eu quero instanciar a classe BaseDocument em outro lugar e usar a propriedade lá. Isso vai matar a idéia de uma propriedade de qualquer maneira.

Uma maneira de corrigir isso seria usar uma interface, dizem IDoc, que expõe DocPath propriedade e fazer tanto o BaseDocument e DerivedDocument implementar a interface. Isso vai quebrar a sua relação pai-filho embora.

Eu posso jogar com os novos e substituir palavras-chave, mas isso não é o caminho certo ou porque a criança ainda 'vê' a propriedade

Eu tentei usar a palavra-chave 'selada' na DocContent, mas isso não parece resolver o problema.

Eu entendo que é herança 'breaks', mas acho que este cenário deve ser chegando freqüentemente onde uma criança precisa para começar tudo outra do pai, mas uma ou duas propriedades.

Como podem tais cenários ser manuseado graciosamente?

Publicado 27/08/2009 em 05:26
fonte usuário
Em outras línguas...                            


7 respostas

votos
3

Você pode fazê-lo facilmente se você não se importa de ter BaseDocument e DerivedDocument em diferentes montagens / projetos.

Faça DocContent interno. Será visível para tudo no mesmo projeto que BaseDocument, mas não será visível para DerivedDocument já que é em um projeto diferente. Claro, você vai precisar para fazer pública BaseDocument (agora você tem isso como padrão, interna).

Em primeiro projeto:

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

No segundo projeto que faz referência em primeiro lugar:

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

Esta solução tem a vantagem de não ser um truque. Você ainda pode usar a propriedade DocContent de BaseDocument dentro do projeto de BaseDocument. Se você precisa usar DocContent em outro projeto (separado do DerivedDocument projeto está em), você pode usar o InternalsVisibleTo atribuir a fazer DocContent visível para que a montagem. (Isso, no entanto, é na minha opinião um remendo, ainda que muito útil em alguns cenários.)

Respondeu 27/08/2009 em 05:52
fonte usuário

votos
3

Eu não tenho certeza herança seria o caminho a percorrer aqui. Sim, você pode cortar em torno dele usando a EditorBrowsableAttribute mas acho que o projeto deve ser repensada. Uma abordagem possível:

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

     }
}

Basicamente, use composição em vez de herança, e programa a uma interface, não para uma implementação.

Respondeu 27/08/2009 em 05:45
fonte usuário

votos
2

Parece que você quer violar intencionalmente a substituição de Liskov. Por que se preocupar com a criação de subclasses em tudo, se não vai ter a semântica de herança convencionais? Basta fazer uma classe separada.

Respondeu 27/08/2009 em 05:49
fonte usuário

votos
1
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) ; 
    }
}
Respondeu 27/08/2009 em 05:51
fonte usuário

votos
0

A reação tardia, mas existem várias maneiras de fazer isso.

Mais bonita: Posicione a Baseclasse em um assembly separado e marcar a propriedade DocContentcomo internalem vez de public:

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

Ou usar attributespara ocultar a propriedade do editor de código:

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
  }
}
Respondeu 29/04/2013 em 16:38
fonte usuário

votos
0

Eu não acredito que há uma boa (ou qualquer) maneira de fazer isso. Você pode ter que quebrar a hierarquia, ou você pode remover a propriedade DocContent de BaseDocument, então derivar duas classes sepearate de BaseDocument, aquele que é o seu DerivedDocument atual, e outra que tem a propriedade DocContent.

Respondeu 27/08/2009 em 05:39
fonte usuário

votos
-1

Basta fazer isso.

class BaseDocument
{
    public DocPath{get; set;}
    public virtual DocContent{get; set;}
} 

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

Ou

public override DocContent 
{ 
    get { throw new NotImplementedException("Do not use this property!"); }
    set { throw new NotImplementedException("Do not use this property!"); } 
} 
Respondeu 27/08/2009 em 05:37
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more