2009-12-08 9 views
25

Se hoCome chiamare internamente i metodi di implementazione dell'interfaccia esplicita senza casting esplicito?

public class AImplementation:IAInterface 
{ 
    void IAInterface.AInterfaceMethod() 
    { 
    } 

    void AnotherMethod() 
    { 
     ((IAInterface)this).AInterfaceMethod(); 
    } 
} 

Come chiamare AInterfaceMethod() da AnotherMethod() senza cast esplicito?

+0

Qual è il problema con il cast? – adrianm

+0

Mi sono appena accigliato quando ho scoperto questa funzione del linguaggio. È molto utile quando si implementano alcune interfacce come IConeable. –

+2

Perché non farlo al contrario? Sposta il codice dal metodo dell'interfaccia esplicita in un metodo "normale". Quindi lascia che tutti i metodi (incluso il metodo dell'interfaccia esplicita) chiamino quel metodo. – adrianm

risposta

-3

Non puoi semplicemente rimuovere "IAInterface". dalla firma del metodo?

public class AImplementation : IAInterface 
{ 
    public void AInterfaceMethod() 
    { 
    } 

    void AnotherMethod() 
    { 
     this.AInterfaceMethod(); 
    } 
} 
+1

Quindi non sarà un'implementazione esplicita. –

8

provato questo e funziona ...

public class AImplementation : IAInterface 
{ 
    IAInterface IAInterface; 

    public AImplementation() { 
     IAInterface = (IAInterface)this; 
    } 

    void IAInterface.AInterfaceMethod() 
    { 
    } 

    void AnotherMethod() 
    { 
     IAInterface.AInterfaceMethod(); 
    } 
} 
0

Non è possibile, ma se si deve fare un sacco si potrebbe definire un aiutante convenienza:

private IAInterface that { get { return (IAInterface)this; } }

Ogni volta che si desidera chiamare un metodo di interfaccia implementato in modo esplicito, è possibile utilizzare that.method() anziché ((IAInterface)this).method().

+1

Vale la pena notare che non è necessario un cast esplicito qui (poiché esiste una conversione implicita da 'this' a' IAInterface' che è implements). –

5

È possibile introdurre un aiutante proprietà privata:

private IAInterface IAInterface { get { return this; } } 

void IAInterface.AInterfaceMethod() 
{ 
} 

void AnotherMethod() 
{ 
    IAInterface.AInterfaceMethod(); 
} 
49

Un certo numero di risposte dicono che non si può. Sono sbagliati Ci sono molti modi per farlo senza usare l'operatore di cast.

Tecnica n. 1: utilizzare l'operatore "as" anziché l'operatore di trasmissione.

void AnotherMethod() 
{  
    (this as IAInterface).AInterfaceMethod(); // no cast here 
} 

Tecnica n. 2: utilizzare una conversione implicita tramite una variabile locale.

void AnotherMethod() 
{  
    IAInterface ia = this; 
    ia.AInterfaceMethod(); // no cast here either 
} 

Tecnica # 3: scrivere un metodo di estensione:

static class Extensions 
{ 
    public static void DoIt(this IAInterface ia) 
    { 
     ia.AInterfaceMethod(); // no cast here! 
    } 
} 
... 
void AnotherMethod() 
{  
    this.DoIt(); // no cast here either! 
} 

Tecnica # 4: Introdurre un aiutante:

private IAInterface AsIA() { return this; } 
void AnotherMethod() 
{  
    this.AsIA().IAInterfaceMethod(); // no casts here! 
} 
+5

Per essere pedante, non ha chiesto di non utilizzare "l'operatore del cast", ha chiesto "senza casting esplicito", e penso che, in generale, l'operatore 'as' sarebbe considerato" casting esplicito "(nessuna idea se questo è corretto in termini di definizioni di specifiche linguistiche, o se la domanda è addirittura priva di significato in quel contesto). –

+1

Bene, la semantica dell'operatore di cast e la semantica dell'operatore as sono abbastanza diversi, quindi è un errore logico confilarli. Vedi http://beta.blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx per i dettagli. –

+6

So che è piuttosto vecchio, ma oggi mi sono imbattuto in questa domanda. Ho ragione a pensare che il modo migliore sia quello implicito? Questo offre la migliore protezione in fase di compilazione per il codice sono corretto? Se sono andato con il cast o con l'operazione "as" (che in questo contesto non ha alcun senso, dal momento che l'oggetto dovrebbe implementare l'interfaccia in primo luogo) corro il rischio di provare a trasmettere un'interfaccia non valida che mi dà un errore di runtime. Se provo a eseguire il cast implicito su un'interfaccia che la classe non implementa, ricevo invece un errore di compilazione, con molto meglio. – julealgon

0

Ancora un altro modo (non migliore):

(this ?? default(IAInterface)).AInterfaceMethod(); 
1

E ancora un altro modo (che è uno spin off di Eric's Technique # 2 e dovrebbe anche dare un errore di compilazione se l'interfaccia non è implementata)

 IAInterface AsIAInterface 
    { 
     get { return this; } 
    } 
Problemi correlati