2009-12-08 13 views
25

Jeśli mamJak wywoływać metody implementacji jawnych interfejsów wewnętrznie bez jawnego przesyłania?

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

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

Jak wywołać AInterfaceMethod() z AnotherMethod() bez wyraźnej castingu?

+0

Jaki jest problem z obsadą? – adrianm

+0

Właśnie zmarszczyłem brwi, gdy odkryłem tę funkcję języka. Jest to bardzo przydatne przy implementowaniu niektórych interfejsów, takich jak ICloneable. –

+2

Dlaczego nie zrobić tego na odwrót? Przenieś kod z jawnej metody interfejsu do "normalnej" metody. Następnie pozwól, aby wszystkie metody (w tym jawna metoda interfejsu) wywoływały tę metodę. – adrianm

Odpowiedz

-3

Nie możesz po prostu usunąć "IAInterface". z podpisem metody?

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

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

To nie będzie wyraźna implementacja. –

8

Próbowałem to i to działa ...

public class AImplementation : IAInterface 
{ 
    IAInterface IAInterface; 

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

    void IAInterface.AInterfaceMethod() 
    { 
    } 

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

Nie możesz, ale jeśli trzeba to zrobić dużo można określić pomocnika Wygoda:

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

Zawsze, gdy chcesz wywołać metodę interfejsu, która została zaimplementowana jawnie, możesz użyć that.method() zamiast ((IAInterface)this).method().

+1

Warto zauważyć, że nie potrzebujesz tutaj wyraźnej obsady (ponieważ istnieje niejawna konwersja z 'this' na' IAInterface', która jest implementowana). –

5

Można wprowadzić pomocnika własności prywatnej:

private IAInterface IAInterface { get { return this; } } 

void IAInterface.AInterfaceMethod() 
{ 
} 

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

Wiele odpowiedzi, że nie można. Są niepoprawne. Istnieje wiele sposobów na to, bez korzystania z operatora obsady.

Technika # 1: Użyj operatora "as" zamiast operatora cast.

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

Technika # 2: użyj niejawnej konwersji za pomocą zmiennej lokalnej.

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

Technika # 3: napisać metodę rozszerzenia:

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

Technika # 4: wprowadzenie pomocnika:

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

Aby być pedantycznym, nie prosił, by nie używać "operatora obsady", prosił o "bez wyraźnego rzucania", i myślę, że ogólnie rzecz biorąc, operator 'as' byłby uważany za" wyraźny casting "(nie ma pojęcia jeśli jest to poprawne pod względem definicji specyfikacji językowych, czy w tym kontekście pytanie jest nawet bez znaczenia). –

+1

Cóż, semantyka operatora rzutowania i semantyka operatora as są zupełnie inne, więc logicznym błędem jest ich łączenie. Szczegółowe informacje można znaleźć na stronie http://beta.blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx. –

+6

Wiem, że jest dość stary, ale natknąłem się dzisiaj na to pytanie. Czy mam rację, sądząc, że "najlepszą" drogą jest niejawna obsada? Zapewnia to najlepszą ochronę w czasie kompilacji kodu, czy mam rację? Gdybym poszedł albo z castingiem, albo z operacją "as" (co właściwie nie ma sensu w tym kontekście, ponieważ obiekt powinien implementować interfejs w pierwszej kolejności), ryzykuję, że spróbuję rzucić na nieprawidłowy interfejs, dając mi błąd środowiska wykonawczego. Jeśli próbuję niejawnie rzutować na interfejs, którego klasa nie implementuje, otrzymuję błąd czasu kompilacji, a jest on znacznie lepszy. – julealgon

0

jeszcze inny sposób (nie najlepszy):

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

A jeszcze inny sposób (który jest spin off of Eric's Technique # 2, a także powinien dać błąd czasu kompilacji, jeśli interfejs nie jest zaimplementowany)

 IAInterface AsIAInterface 
    { 
     get { return this; } 
    } 
Powiązane problemy