2014-09-09 4 views
6

Ok, questo deriva da alcune discussioni in corso here.Implementare due volte un'interfaccia esplicita per ottenere un comportamento "virtuale" come un brutto attacco?

Immaginate il seguente scenario. Società Alpha pubblica biblioteca Charlie che espone, tra gli altri, un tipo Charlie.Bar che explicilty implementa l'interfaccia IFooable:

public interface IFooable 
{ 
    void Foo(); 
} 

namespace Charlie 
{ 
    public clas Bar: IFooable 
    { 
     void IFooable.Foo() {...} 
     .... 
    } 
} 

Ora accade che società Beta è sottoclassi Charlie.Bar nella sua libreria Tango per alcuni molto particolari funzionalità in cui l'implementazione esplicita di IFooable.Foo non lo taglia. Beta deve "ignorare" l'implementazione dell'interfaccia e ottenere un comportamento virtuale apparentemente equivalente; Le chiamate a IFooable.Foo() dovrebbero essere risolte correttamente con il tipo di runtime dell'oggetto. Si noti che la società Alpha modificare l'implementazione di Charlie.Bar non è un'opzione valida.

Quindi, come può essere fatto? I metodi di interfaccia esplicita sono contrassegnati in CIL come virtual e final quindi non è possibile sovrascriverli. Beta si avvicinò con questo "hack":

using Charlie; 

namespace Tango 
{ 
    class Blah: Bar, IFooable 
    { 
     void IFooable.Foo() { //Bar specific implementation } 
    } 
} 

nota l'attuazione di IFooable nuovo in Blah anche se è ridondante. Con questo codice, è effettivamente ottenere lo stesso comportamento di un metodo virtuale al momento della chiamata IFooable.Foo():

IFooable fooBar = new Bar(); 
IFooable fooBlah = new Blah(); 

fooBlah.Foo() // Blah's implementation is called. 
fooBar.Foo() // Bar's implementation is called. 

È questo un brutto hack? (L'ho visto fatto in scenari similmente giustificati). Quali sono le alternative se presenti?

+3

'IFooable' non è ridondante qui. Questa è chiamata re-implementazione dell'interfaccia. La mia risposta [qui] (http://stackoverflow.com/a/25008171/517852) ha alcune spiegazioni su questa funzione. Uno svantaggio è che con la re-implementazione dell'interfaccia non si ha la possibilità di chiamare l'implementazione di base. –

+1

'' Blah' * necessita * di essere un sottotipo di 'Bar'? In caso contrario, è possibile utilizzare la composizione: memorizzare un riferimento a una 'Barra' nella classe' Blah' e inoltrare tutte le chiamate pertinenti a tale. – Medo42

+0

Mikez ha ragione. Non è ridondante o hack. È una [funzionalità] (http://msdn.microsoft.com/en-us/library/aa664594%28v=vs.71%29.aspx). –

risposta

-1

Stai chiedendo opinioni, giusto? Ho programmato C# per 10 anni. Sì, sembra un trucco. Non è brutto, ma se dovessi scrivere la libreria Tango, proverei a isolare quel codice.

Se ho trovato la re-implementazione dell'interfaccia come soluzione per alcuni problemi di progettazione nel mio code-base in cui controllo sia Bar che Blah, suggerirei che si tratta di una progettazione eccessiva.

Problemi correlati