2009-04-03 16 views

Respuesta

13

Otro aspecto de esta:

Si implícitamente implementado, significa que los elementos de interfaz son accesibles a usuarios de su clase sin que tengan que lanzarlo.

Si se implementa explícitamente, los clientes tendrán que enviar su clase a la interfaz antes de poder acceder a los miembros. He aquí un ejemplo de una implementación explícita:

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() 
    { 
    } 

} 

su código de cliente

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

La diferencia es que se puede heredar una clase a partir de varias interfaces. Estas interfaces pueden tener firmas de Método idénticas. Una implementación explícita le permite cambiar su implementación según la Interfaz utilizada para llamarla.

4

Explícito pondrá IInterfaceName. al frente de todas las implementaciones de interfaz. Es útil si necesita implementar dos interfaces que contienen nombres/firmas que entran en conflicto.

Más información here.

10

El IDE le da la opción para hacer cualquiera - sería inusual hacer ambas cosas. Con la implementación explícita, los miembros no están en la API pública (primaria); esto es útil si la interfaz no está directamente relacionada con la intención del objeto. Por ejemplo, los miembros ICustomTypeDescriptor no son tan útiles para las personas que llaman con regularidad, solo para un código muy específico, por lo que no tiene sentido tenerlos en la API pública causando desorden.

Esto también es útil si:

  • hay un conflicto entre Foo método de una interfaz y método Foo de su propio tipo, y ellos significan cosas diferentes
  • hay un conflicto firma entre otras interfaces

El ejemplo típico del último punto es IEnumerable<T>, que tiene un método GetEnumerator() en dos niveles en la jerarquía de la interfaz. Es común que impl Haga clic en la versión mecanografiada (IEnumerator<T>) utilizando la implementación implícita y la versión sin tipo (IEnumerator) utilizando la implementación explícita.

+1

La implementación explícita también es útil cuando su clase necesita implementar una interfaz interna que no desea exportar públicamente desde su ensamblado. – Dave

1

explícitamente aplicar pone el nombre completo en el nombre de la función en cuenta este código

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

implementación de interfaz explícita, donde se oculta la aplicación a menos que convierta explícitamente, es más útil cuando la interfaz es ortogonal a la funcionalidad de clase Es decir, sin relación de comportamiento.

Por ejemplo, si su clase es Persona y la interfaz es ISerializable, no tiene mucho sentido para alguien que trata con los atributos de Persona ver algo extraño llamado 'GetObjectData' a través de Intellisense. Por lo tanto, es posible que desee implementar explícitamente la interfaz.

Por otro lado, si su clase de persona implementa IAddress, tiene mucho sentido ver miembros como AddressLine1, ZipCode, etc. en las instancias Person directamente (implementación implícita).

6

Aquí está la diferencia en la llanura Inglés:

Suponga que tiene una interfaz Machine, que tiene una función Run(), y otra interfaz Animal que también tiene una función llamada Run(). Por supuesto, cuando una máquina funciona, estamos hablando de que está comenzando, pero cuando un animal corre, estamos hablando de que se mueve. Entonces, ¿qué sucede cuando tienes un objeto, vamos a llamarlo Aibo que es a la vez y Animal? (Aibo es un perro mecánico, por cierto). Cuando se ejecuta Aibo, ¿se inicia o se mueve? Explícitamente la implementación de una interfaz le permite hacer esta distinción:

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(); 
    } 
} 

El truco aquí es que no puedo simplemente llamar a.Run() porque mis dos implementaciones de la función están unidas de forma explícita a una interfaz. Eso tiene sentido, porque de lo contrario, ¿cómo sabría el recopilador a cuál llamar? En cambio, si quiero llamar directamente a la función Run() en mi Aibo, tendré que también implementar esa función sin una interfaz explícita.

Cuestiones relacionadas