2009-04-03 6 views

Répondre

13

Un autre aspect de ceci:

Si vous implicitement mis en œuvre, cela signifie que les membres d'interface sont accessibles à utilisateurs de votre classe sans qu'ils aient à le lancer.

Si c'est explicitement implémenté, les clients devront lancer votre classe à l'interface avant de pouvoir accéder aux membres. Voici un exemple d'une mise en œuvre explicite:

interface Animal 
{ 
    void EatRoots(); 
    void EatLeaves(); 
} 

interface Animal2 
{ 
    void Sleep(); 
} 


class Wombat : Animal, Animal2 
{ 
    // Implicit implementation of Animal2 
    public void Sleep() 
    { 
    } 

    // Explicit implementation of Animal 
    void Animal.EatRoots() 
    { 

    } 

    void Animal.EatLeaves() 
    { 
    } 

} 

Votre code client

Wombat w = new Wombat(); 
w.Sleep(); 
w.EatRoots(); // This will cause a compiler error because it's explicitly implemented 
((Animal)w).EatRoots(); // This will compile 
0

Ici, vous allez, directement à partir MSDN

0

La différence est que vous pouvez hériter d'une classe de plusieurs interfaces. Ces interfaces peuvent avoir des signatures de méthode identiques. Une implémentation explicite vous permet de modifier votre implémentation en fonction de l'interface utilisée pour l'appeler.

4

Explicit met IInterfaceName. à l'avant de toutes les implémentations d'interface. C'est utile si vous avez besoin d'implémenter deux interfaces contenant des noms/signatures incompatibles.

Plus d'infos here.

10

L'EDI vous donne l'option pour faire l'une ou l'autre - il serait inhabituel de faire les deux. Avec une implémentation explicite, les membres ne sont pas sur l'API publique (primaire); C'est pratique si l'interface n'est pas directement liée à l'intention de l'objet. Par exemple, les membres ICustomTypeDescriptor ne sont pas très utiles aux appelants habituels, mais seulement à un code très spécifique. Il est donc inutile de les avoir sur l'API publique, ce qui pourrait causer des dégâts.

Ceci est également utile si:

  • il y a un conflit entre une méthode de l'interface Foo et votre propre méthode de Type Foo, et ils veulent dire des choses différentes
  • il y a un conflit de signature entre autres interfaces

L'exemple typique du dernier point est IEnumerable<T>, qui a une méthode GetEnumerator() à deux niveaux dans la hiérarchie de l'interface - il est courant d'impliquer ement la version typée (IEnumerator<T>) en utilisant une implémentation implicite, et la version non typée (IEnumerator) en utilisant une implémentation explicite.

+1

Une implémentation explicite est également utile lorsque votre classe doit implémenter une interface interne que vous ne souhaitez pas exporter publiquement à partir de votre assembly. – Dave

1

mettre en œuvre Explicitement met le nom complet sur le nom de la fonction considérer ce code

public interface IamSam 
    { 
     int foo(); 
     void bar(); 
    } 

    public class SamExplicit : IamSam 
    { 
     #region IamSam Members 

     int IamSam.foo() 
     { 
      return 0; 
     } 

     void IamSam.bar() 
     { 

     } 

     string foo() 
     { 
      return ""; 
     } 
     #endregion 
    } 

    public class Sam : IamSam 
    { 
     #region IamSam Members 

     public int foo() 
     { 
      return 0; 
     } 

     public void bar() 
     { 

     } 

     #endregion 
    } 

IamSam var1; 
var1.foo() returns an int. 
SamExplicit var2; 
var2.foo() returns a string. 
(var2 as IamSam).foo() returns an int. 
0

Implémentation d'interface explicite, où la mise en œuvre est masqué, à moins que vous explicitement exprimés, est le plus utile lorsque l'interface est perpendiculaire à la fonctionnalité de classe. C'est-à-dire, sans rapport avec le comportement. Par exemple, si votre classe est Person et que l'interface est ISerializable, cela n'a pas beaucoup de sens pour quelqu'un qui gère les attributs Person de voir quelque chose d'étrange appelé 'GetObjectData' via Intellisense. Vous pourriez donc vouloir implémenter explicitement l'interface. D'autre part, si votre classe de personne arrive à implémenter IAddress, il est logique de voir directement des membres comme AddressLine1, ZipCode etc sur les instances Person (implémentation implicite).

6

est ici la différence en anglais simple:

Supposons que vous ayez une interface Machine, qui a une fonction Run(), et une autre interface Animal qui a également une fonction appelée Run(). Bien sûr, quand une machine tourne, on parle de démarrage, mais quand un animal court, on parle de ça en train de bouger. Alors qu'arrive-t-il lorsque vous avez un objet, appelons-le Aibo qui est à la fois un Machine et un Animal? (Aibo est un chien mécanique, au fait.) Quand Aibo court, démarre-t-il ou se déplace-t-il? la mise en œuvre de façon explicite une interface vous permet de faire cette distinction:

interface Animal 
{ 
    void Run(); 
} 
interface Machine 
{ 
    void Run(); 
} 

class Aibo : Animal, Machine 
{ 
    void Animal.Run() 
    { 
     System.Console.WriteLine("Aibo goes for a run."); 
    } 
    void Machine.Run() 
    { 
     System.Console.WriteLine("Aibo starting up."); 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     Aibo a = new Aibo(); 
     ((Machine)a).Run(); 
     ((Animal)a).Run(); 
    } 
} 

Le problème ici est que je ne peux pas simplement appeler a.Run() parce que mes deux implémentations de la fonction sont explicitement attachés à une interface. Cela a du sens, car sinon, comment le complicateur pourrait-il savoir lequel appeler? Au lieu de cela, si je veux appeler la fonction Run() sur mon Aibo directement, je devrai également implémenter cette fonction sans interface explicite.

Questions connexes