2013-06-18 2 views
5

Definisco essenzialmente IFoo due volte nella classe Inherited. Ciò causa alcune conseguenze impreviste?Definizione dell'interfaccia più volte nella classe ereditata

interface IFoo { 
    ... 
} 

interface IBar : IFoo { 
    ... 
} 

class Base : IFoo { 
    ... 
} 

class Derived : Base, IBar { 
    ... 
} 

Il motivo che voglio fare IBar erediti da IFoo è così posso lavorare su Derived come era IFoo senza dover per lanciarla.

if (Derived is IBar) 
    // Do work 

Se non eredita, devo scriverlo. Che rende più complicato, e gli utenti della classe potrebbero non capire che IBar è solo una specializzazione di IFoo.

if (Derived is IBar) 
    Derived as IFoo 
    // Do work 

Questa cattiva pratica? Quali altre soluzioni ci sono per questo problema?

+0

Perché vuoi fare 'if (Derived is IBar) Derivato come IFoo'? Perché invece 'if (Derived is IFoo)' invece? –

+0

Perché IBar è un'interfaccia marcatore che mi dice che "Derivato" è di un tipo specifico. In questo modo posso tenere tutto IFoo in una collezione e lavorare con tutti loro. Dovrei solo "lavorare" sui tipi di IBar che posso fare .OfType . –

risposta

5

Non causerà circostanze impreviste in termini di codice. È solo ridondante.

Per quanto riguarda questo codice:

if (Derived is IBar) 
    Derived as IFoo 

che è completamente inutile in quanto Derivedè un IFoo, data le dichiarazioni - in modo da non farlo!

Si noti che anche se IBar non deriva da IFoo, non è ancora necessario Derived as IFoo. Dato:

interface IFoo {} 

interface IBar {} 

class Base : IFoo {} 

class Derived : Base, IBar 
{ 
} 

Allora questo compila ok:

var derived = new Derived(); 

IBar bar = derived; // Fine. 
IFoo foo = derived; // Also fine. 
+0

'Derived as IFoo' era un esempio di cosa dovevo fare se' IBar' non derivava da 'IFoo' –

+0

@ Snæbjørn Ma non è vero - anche se' IBar' non deriva da 'IFoo',' Base' fa già così non hai bisogno di 'Derived as IFoo'. Vedi la mia risposta aggiornata. –

+0

Ah sì, è corretto. Sto iniziando a capire che non ho spiegato correttamente il problema :(. Il tuo suggerimento è come farei normalmente, e probabilmente è come dovrei fare. Probabilmente questo dovrebbe essere un altro post, ma qui va. Base e derivati ​​in un 'Elenco '. Voglio estrarre tutti gli 'IBar's dalla lista.Questo faccio usando' list.OfType 'problema è che non riesco a memorizzare quell'elenco in un' Elenco ' senza usare '.Cast ' che non è intuitivo. Sto iniziando a dubitare del mio design :) –

1

È possibile definire esplicitamente un'implementazione per un Interface e così distinguere nei comportamenti

class Derived : Base, IBar { 

    void IBar.Method(){ 

    } 

    void Base.Method() { 

    } 
} 

Oltre a questo, si può fare , ma è ridondante e potrebbe causare confusione. Vedi MSDN.

+0

è che anche la sintassi legale? –

+0

Ho sbagliato su "override", l'articolo MSDN dice che puoi farlo. VS offre anche questa funzione –

+0

Penso che i metodi dovrebbero essere 'private', quindi stai implementando un'interfaccia come quella –

1

Se ho capito bene, hai una gerarchia di interfacce e una gerarchia di classi che si rispecchiano a vicenda. Ogni classe implementa l'interfaccia corrispondente ereditando dalla sua classe base e implementando i membri aggiuntivi necessari.

Questo va bene e lo faccio allo stesso modo. Non conosco un modo migliore per farlo: questo è un buon approccio.

Penso che IBar dovrebbe estendere IFoo proprio come il tuo suggerimento principale, altrimenti i consumatori avrebbero bisogno di lanciare molto. Inoltre, poiché consideri IBar una specializzazione di IFoo, anche ne fanno una specializzazione nel codice, quindi fai in modo di estendere IFoo.