2009-12-08 3 views
25

Si jeComment appeler des méthodes d'implémentation d'interface explicite en interne sans conversion explicite?

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

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

Comment appeler AInterfaceMethod() de AnotherMethod() sans coulée explicite? Vous ne pouvez pas simplement supprimer le "IAInterface."

+0

Quel est le problème avec la distribution? – adrianm

+0

J'ai juste froncé les sourcils quand j'ai découvert cette fonction de langue. C'est très utile lors de l'implémentation de certaines interfaces comme IClonable. –

+2

Pourquoi ne pas le faire dans l'autre sens? Déplacez le code de la méthode d'interface explicite vers une méthode "normale". Ensuite, laissez simplement toutes les méthodes (y compris la méthode d'interface explicite) appeler cette méthode. – adrianm

Répondre

-3

de la signature de la méthode?

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

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

Ensuite, ce ne sera pas une implémentation explicite. –

8

essayé et ça fonctionne ...

public class AImplementation : IAInterface 
{ 
    IAInterface IAInterface; 

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

    void IAInterface.AInterfaceMethod() 
    { 
    } 

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

Vous ne pouvez pas, mais si vous devez le faire beaucoup vous pouvez définir une aide de commodité:

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

Chaque fois que vous souhaitez appeler une méthode d'interface explicitement implémentée, vous pouvez utiliser that.method() au lieu de ((IAInterface)this).method().

+1

Il est à noter que vous n'avez pas besoin d'une distribution explicite ici (puisqu'il y a une conversion implicite de 'this' à' IAInterface' qui est implements). –

5

Vous pouvez introduire une aide propriété privée:

private IAInterface IAInterface { get { return this; } } 

void IAInterface.AInterfaceMethod() 
{ 
} 

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

Un certain nombre de réponses disent que vous ne pouvez pas. Ils sont incorrects. Il y a beaucoup de façons de le faire sans utiliser l'opérateur de casting.

Technique n ° 1: Utiliser l'opérateur "as" à la place de l'opérateur de moulage.

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

Technique n ° 2: utiliser une conversion implicite via une variable locale.

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

Technique # 3: écrire une méthode d'extension:

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

Technique # 4: Mettre en place une aide:

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

Pour être pédant, il n'a pas demandé de ne pas utiliser "l'opérateur cast", il a demandé "sans casting explicite", et je pense que, d'une manière générale, l'opérateur 'as' serait considéré comme" casting explicite "(aucune idée si c'est exact en termes de définitions de spécifications de langage, ou si la question est même vide de sens dans ce contexte). –

+1

Eh bien, la sémantique de l'opérateur cast et la sémantique de l'opérateur as sont très différentes, donc c'est une erreur logique de les confondre. Voir http://beta.blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx pour plus de détails. –

+6

Je sais que c'est assez vieux, mais je suis tombé sur cette question aujourd'hui. Ai-je raison de penser que la «meilleure» voie est la distribution implicite? Cela offre la meilleure protection de temps de compilation pour le code suis-je correct? Si je suis allé soit avec le casting ou l'opération "as" (ce qui n'a aucun sens dans ce contexte, puisque l'objet est supposé implémenter l'interface en premier lieu) je risque d'essayer de lancer une interface non valide une erreur d'exécution. Si j'essaie de lancer implicitement vers une interface que la classe n'implémente pas, j'obtiens une erreur de compilation à la place, avec c'est beaucoup mieux. – julealgon

0

Encore une autre façon (pas le meilleur):

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

Et encore une autre façon (qui est une spin-off de La technique n ° 2 d'Eric et devrait aussi donner une erreur de compilation si l'interface n'est pas implémentée)

 IAInterface AsIAInterface 
    { 
     get { return this; } 
    }