c # cacher des classes dervied certaines propriétés de la classe de base

voix
0

Je veux savoir s'il est possible de cacher une propriété de classe de base à partir d'une classe dérivée:

Exemple:

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

Je ne peux pas privé, la propriété docContent parce que je veux instancier la classe BaseDocument ailleurs et utiliser la propriété là-bas. Cela tue l'idée d'une propriété de toute façon.

Une façon de résoudre ce problème serait d'utiliser une interface, par exemple IDOC, qui expose la propriété DocPath et faire à la fois la BaseDocument et DerivedDocument mettre en œuvre l'interface. Ceci brisera la relation parent-enfant cependant.

Je peux jouer avec les nouveaux et les mots clés override, mais ce n'est pas la bonne façon, soit parce que l'enfant « voit » toujours la propriété

J'ai essayé d'utiliser le mot-clé « étanche » sur le docContent, mais cela ne semble pas résoudre le problème non plus.

Je comprends que ce patrimoine « pauses », mais je suppose que ce scénario devrait être à venir souvent lorsqu'un enfant a besoin d'obtenir tout le reste du parent, mais une ou deux propriétés.

Comment ces scénarios sont gérés de façon élégante?

Créé 27/08/2009 à 05:26
source utilisateur
Dans d'autres langues...                            


7 réponses

voix
3

Vous pouvez le faire facilement si vous ne me dérange pas d'avoir BaseDocument et DerivedDocument dans différents ensembles / projets.

Faire docContent interne. Il sera visible à tout dans le même projet que BaseDocument, mais il ne sera pas visible à DerivedDocument puisque c'est dans un autre projet. Bien sûr, vous aurez besoin de rendre publics BaseDocument (que vous avez maintenant comme la valeur par défaut, interne).

Dans le premier projet:

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

Dans la deuxième projet qui fait référence à la première:

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

Cette solution a l'avantage de ne pas être une bidouille. Vous pouvez toujours utiliser la propriété docContent de BaseDocument au sein du projet de BaseDocument. Si vous avez besoin d'utiliser docContent dans un autre projet (distinct du projet DerivedDocument est en), vous pouvez utiliser l'attribut InternalsVisibleTo pour rendre docContent visible à cette assemblée. (Cela, cependant, est à mon avis une bidouille, quoique très pratique dans certains scénarios.)

Créé 27/08/2009 à 05:52
source utilisateur

voix
3

Je ne suis pas sûr que l' héritage serait la voie à suivre ici. Oui, vous pouvez pirater autour d' elle en utilisant le EditorBrowsableAttribute mais je pense que la conception devrait être repensée. Une approche possible:

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

     }
}

Fondamentalement, utiliser la composition au lieu de l'héritage et le programme à une interface, pas à une mise en œuvre.

Créé 27/08/2009 à 05:45
source utilisateur

voix
2

On dirait que vous voulez violer intentionnellement le Liskov principe de substitution. Pourquoi se préoccuper de subclassing du tout si ça ne va pas avoir la sémantique de l'héritage classique? Il suffit de faire une classe séparée.

Créé 27/08/2009 à 05:49
source utilisateur

voix
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) ; 
    }
}
Créé 27/08/2009 à 05:51
source utilisateur

voix
0

Une réaction tardive, mais il y a plusieurs façons de le faire.

Le plus beau: Placez votre Baseclasse dans un ensemble séparé et marquer la propriété DocContentcomme internallieu de public:

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

Ou utiliser attributespour cacher la propriété de l'éditeur de source:

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
  }
}
Créé 29/04/2013 à 16:38
source utilisateur

voix
0

Je ne crois pas qu'il y ait un bon (ou tout autre) façon de le faire. Vous pourriez avoir à briser la hiérarchie, ou vous pouvez supprimer la propriété docContent de BaseDocument, déduisons deux classes sepearate de BaseDocument, celui qui est votre DerivedDocument actuelle, et un autre qui a la propriété docContent.

Créé 27/08/2009 à 05:39
source utilisateur

voix
-1

Il suffit de le faire.

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!"); } 
} 
Créé 27/08/2009 à 05:37
source utilisateur

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