c # skrýt z dervied tříd některé vlastnosti základní třídy

hlasů
0

Chci vědět, jestli jeho možné skrýt vlastnost základní třídy z odvozené třídy:

Příklad:

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

Nemohu dělat vlastnost DocContent soukromí, protože chci vytvořit instanci třídy BaseDocument jinde a použít vlastnost existuje. Že zabije myšlenku vlastnictví tak jako tak.

Jeden způsob, jak to napravit, by bylo použít rozhraní, řekněme IDOC, která vystavuje vlastnost DocPath a aby oba BaseDocument a DerivedDocument implementovat rozhraní. Tím se zlomit jejich rodič-dítě vztahy ačkoli.

Můžu hrát s novými a potlačí klíčová slova, ale to není ta správná cesta a to buď proto, že dítě ještě ‚vidí‘ vlastnost

Snažil jsem se pomocí ‚uzavřený‘ klíčové slovo na DocContent, ale nezdá se, že vyřešit problém jeden.

Chápu, že to dědictví ‚rozbije‘, ale myslím, že tento scénář je třeba přijít častěji, pokud dítě potřebuje dostat všechno ostatní od rodiče, ale jednou nebo dvěma vlastnostmi.

Jak mohou tyto scénáře být řešeny elegantně?

Položena 27/08/2009 v 05:26
zdroj uživatelem
V jiných jazycích...                            


7 odpovědí

hlasů
3

Můžete to udělat snadno, pokud vám nevadí, že má BaseDocument a DerivedDocument v různých sestavách / projektech.

Udělat DocContent vnitřní. Bude to vidět na vše ve stejném projektu jako BaseDocument, ale nebude viditelný DerivedDocument, protože to je v jiném projektu. Samozřejmě, budete muset provést BaseDocument veřejnosti (právě teď máte jako výchozí, vnitřní).

V prvním projektu:

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

V druhém projektu, který odkazuje na první:

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

Toto řešení má tu výhodu, že se nejedná o kludge. Můžete i nadále používat své BaseDocument DocContent majetku v rámci projektu BaseDocument je. Pokud potřebujete použít DocContent v jiném projektu (odděleně od DerivedDocument projektu je), můžete použít InternalsVisibleTo atribut, aby DocContent viditelné této sestavy. (To však je podle mého názoru kludge, byť velmi šikovný jeden v některých případech).

Odpovězeno 27/08/2009 v 05:52
zdroj uživatelem

hlasů
3

Nejsem si jistý, dědičnost by byl způsob, jak jít sem. Ano, můžete zaseknout kolem něj pomocí EditorBrowsableAttribute ale myslím, že návrh by měl být přehodnoceny. Jedním z možných přístupů:

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

     }
}

Zjednodušeně řečeno, pomocí složení místo dědictví, a program pro rozhraní, nikoli k realizaci.

Odpovězeno 27/08/2009 v 05:45
zdroj uživatelem

hlasů
2

Vypadá to, že chcete, aby úmyslně porušit princip Střídání Liskov. Proč se obtěžovat s subclassing vůbec, pokud to nebude mít obvyklé dědické sémantiku? Jen se samostatnou třídu.

Odpovězeno 27/08/2009 v 05:49
zdroj uživatelem

hlasů
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) ; 
    }
}
Odpovězeno 27/08/2009 v 05:51
zdroj uživatelem

hlasů
0

Pozdní reakce, ale existuje několik způsobů, jak toho dosáhnout.

Nejkrásnější: umístěte Basetřídu v samostatném shromáždění a označte vlastnost DocContentjako internalmísto public:

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

Nebo použijte attributesskrýt majetek ze zdrojového editoru:

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
  }
}
Odpovězeno 29/04/2013 v 16:38
zdroj uživatelem

hlasů
0

Nevěřím, že tam je dobrá (nebo) způsob, jak to udělat. Možná se budete muset rozbít hierarchii, nebo můžete odstranit vlastnost DocContent z BaseDocument, pak odvodit dvě sepearate třídy z BaseDocument, ten, který je aktuální DerivedDocument, a druhého, který má vlastnost DocContent.

Odpovězeno 27/08/2009 v 05:39
zdroj uživatelem

hlasů
-1

Prostě to udělat.

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

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

Nebo

public override DocContent 
{ 
    get { throw new NotImplementedException("Do not use this property!"); }
    set { throw new NotImplementedException("Do not use this property!"); } 
} 
Odpovězeno 27/08/2009 v 05:37
zdroj uživatelem

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