2011-11-04 7 views
8

utilizzando C# Ho una classe che contiene tra le altre meta informazioni il nodo radice di un grafico diretto. Chiamiamo questo Classe contenitore. Questo contenitore può apparire in due diverse modalità, modalità Editor e modalità configuratore. A seconda della modalità, il nodo principale è di tipo diverso NodeEdit o NodeConfig, entrambi che ereditano dalla stessa sottoclasse.Modifica del tipo di una proprietà ereditata (in un tipo ereditato)

public abstract class NodeBase 
{ 
    string Name { get; set; } 
    ... 
} 

public class NodeEdit : NodeBase ... 
public class NodeConfig : NodeBase ... 

Per il contenitore, ho anche creare una classe di base ed ereditare da essa:

public abstract class ContainerBase 
{ 
    NodeBase Root { get; set; } 
    ... 
} 

Quando si creano le classi per Editor- e Configuratorcontainer ereditando da ContainerBase, voglio diventare il tipo di la radice - proprietà specifica (ereditato da NodeBase) tipo come:

public class ContainerEditor : ContainerBase 
{ 
    NodeEditor Root { get; set; } 
    ... 
} 

Ma non può cambiare il tipo di una proprietà definita in ContainerBase. c'è un modo per risolvere questo problema? Posso usare il BaseNode-tipo, e aggiungere un elemento di NodeEditor come

ContainerEditorInstance.Root = new NodeEditor(); 

perché il tipo NodeEditor viene ereditato dal tipo BaseEditor, ma nella classe Container-Editor, voglio permettere esplicitamente solo il tipo di Proprietà root per essere NodeEditor. Potrei controllare questo nel setter e rifiutare tutti i nodi ma quelli di tipo NodeEditor, ma mi piacerebbe che la proprietà fosse del tipo specifico, così posso rilevare assegnazioni errate in fase di compilazione.

Grazie in anticipo,
Frank

risposta

4

Puoi ridichiarare esso:

public class ContainerEditor : ContainerBase 
{ 
    public NodeEditor Root { 
    get { return (NodeEditor)base.Root; } 
    set { base.Root = value; } 
    } 
    ... 
} 
+0

Ciao Marc, grazie per la risposta! L'avevo già provato con la redeclaration, ma probabilmente ho fatto qualcosa di sbagliato. Ho testato il tuo approccio e funziona perfettamente! Generalmente, ci sono situazioni in cui la redeclaring dovrebbe essere preferita a Generics o viceversa o sono uguali? – Aaginor

+0

Tutta questa roba generica sta causando seri problemi quando si deve usare la classe base generica, cioè come un tipo di ritorno astratto.Quindi darò un nuovo colpo al redeclaring, perché sembra essere meno invadente. In confronto a "nuovo" e "override", in che modo la redeclaring funziona internamente? C'è qualche buon articolo che puoi raccomandare? Grazie ancora! – Aaginor

9

Utilizzare farmaci generici:

public abstract class ContainerBase<T> where T:NodeBase 
{ 
    T Root { get; set; } 
    ... 
} 

public class ContainerEditor : ContainerBase<NodeEditor> 
{  
    ... 
} 
+0

Hi Blau, mai affrontato con i generici accanto alla solita HashSet e l'uso di simili. Pensa che probabilmente questo sarà un buon momento per lavorare con loro! – Aaginor

1

si può fare la base del contenitore generico:

public abstract class ContainerBase<TRoot> where TRoot : NodeBase 
{ 
    TRoot Root { get; set; } 
    ... 
} 

Nella classe derivata di specificare il tipo:

public class ContainerEditor : ContainerBase<NodeEditor> 
{ 
    ... 
} 
+0

Buona idea, farò un tentativo. – Aaginor

0

Suppongo che una buona soluzione qui sarà Generics. Quindi devi scrivere qualcosa di simile:

public class ContainerEditor<T>:ContainerBase 
{ 
    T Root {get;set;} 
} 
+0

Avrei bisogno di dichiarare il Root in ContainerBase per poterlo accedere in funzioni che non hanno bisogno di sapere se sono l'Editor o il Configuratore. In ogni caso i generici sembrano una buona idea, come hanno mostrato Guffa e Blau. – Aaginor

Problemi correlati