usan una sirven que programacion para las interfaz interfaces implementacion ejemplos declaracion como atributos c# interface implicit explicit-interface

c# - una - ¿Por qué utilizar la implementación de interfaz explícita para invocar un método protegido?



para que sirven las interfaces en java (3)

Al navegar por el código fuente ASP.NET MVC en codeplex , encontré que es común tener una clase implementando explícitamente la interfaz. El método / propiedad implementado explícitamente evoca otro método / propiedad "protegido virtual" con el mismo nombre.

Por ejemplo,

public class MvcHandler : IHttpHandler, IRequiresSessionState { protected virtual bool IsReusable { get { return false; } } bool IHttpHandler.IsReusable { get { return IsReusable; } } }

Ahora estoy seguro de cuál es el beneficio de este tipo de programación. Para mí, prefiero implementar implícitamente la interfaz IHttpHandler.

Supongo que el autor simplemente no quiere que MvcHandler tenga una propiedad pública IsResuable . La propiedad IsReusable solo se puede usar cuando la instancia de MvcHandler se trata como un IHttpHandler . Aún así, no estoy seguro de por qué el autor de esta manera.

¿Alguien sabe más beneficios sobre este estilo de implementación de interfaz?


Bueno, no es específico de MVC, pero este enfoque te permite mantener limpia la API pública central . También es útil si existe el riesgo de que diferentes interfaces / etc tengan el mismo nombre y firma, pero con un significado diferente. En realidad esto es raro.

También le permite proporcionar una implementación en la que desea que el tipo de devolución cambie en las subclases:

( ICloneable elegido por simplicidad - no se deje llevar por el hecho de que es una interfaz mal definida ... un ejemplo mejor hubiera sido cosas como DbCommand , etc., que hacen esto), pero eso es más difícil de mostrar en un breve ejemplo )

class Foo : ICloneable { public Foo Clone() { return CloneCore(); } object ICloneable.Clone() { return CloneCore(); } protected virtual Foo CloneCore() { ... } } class Bar : Foo { protected override Foo CloneCore() { ... } public new Bar Clone() { return (Bar)CloneCore(); } }

Si hubiéramos usado un método virtual público, no podríamos override y usar el new en la clase base, ya que no tiene permitido hacer ambas cosas:

class A { public virtual A SomeMethod() { ... } } class B : A { public override A SomeMethod() { ... } //Error 1 Type ''B'' already defines a member called ''SomeMethod'' with the same parameter types public new B SomeMethod() { ... } }

Usando el enfoque virtual protegido, cualquier uso:

  • Foo.Clone ()
  • Bar.Clone ()
  • ICloneable.Clone ()

todos usan la implementación correcta de CloneCore() para el tipo concreto.


  1. Cuando un miembro se implementa explícitamente, no se puede acceder a través de una instancia de clase, sino solo a través de una instancia de la interfaz. referencia: Tutorial explícito de implementación de interfaz
  2. Como mi experiencia con el implementador de interfaz explícitamente implementa una interfaz, recibirá un error de compilación después de que suelte un método de la interfaz, mientras que no notificará si lo implementa implícitamente y el método permanecerá en el código.

muestra por razón 1:

public interface IFoo { void method1(); void method2(); } public class Foo : IFoo { // you can''t declare explicit implemented method as public void IFoo.method1() { } public void method2() { } private void test() { var foo = new Foo(); foo.method1(); //ERROR: not accessible because foo is object instance method1(); //ERROR: not accessible because foo is object instance foo.method2(); //OK method2(); //OK IFoo ifoo = new Foo(); ifoo.method1(); //OK, because ifoo declared as interface ifoo.method2(); //OK } }


Si una clase implementa IFoo.Bar explícitamente, y una clase derivada necesita IFoo.Bar para hacer algo diferente, no habrá forma de que la clase derivada IFoo.Bar implementación de clase base de ese método. Una clase derivada que no vuelve a implementar IFoo.Bar podría llamar a la implementación de la clase base a través de ((IFoo)this).Bar() , pero si la clase derivada vuelve a implementar IFoo.Bar (como debería hacerlo en orden para cambiar su comportamiento) la llamada mencionada iría a la reimplementación de la clase derivada, en lugar de a la implementación de la clase base. Incluso ((IFoo)(BaseType)this).bar no ayudaría, ya que al hacer una referencia a un tipo de interfaz se descartará cualquier información sobre el tipo de referencia (a diferencia del tipo de instancia de instancia) que se emitió.

Tener una implementación de interfaz explícita no hacer nada más que llamar a un método protegido evita este problema, ya que una clase derivada puede cambiar el comportamiento del método de interfaz anulando el método virtual, conservando la capacidad de llamar a la implementación base como lo considere oportuno. En mi humilde opinión, C # debería haber tenido una implementación de interfaz explícita para producir un método virtual con un nombre compatible con CLS, por lo que alguien escribiendo en C # una derivada de una clase que implementó explícitamente IFoo.Bar podría override void IFoo.Bar , y alguien escribiendo en algún otro lenguaje podría decir, por ejemplo, Overrides Sub Explicit_IFoo_Bar() ; dado que cualquier clase derivada puede volver a implementar IFoo.Bar , y dado que cualquier clase derivada que no vuelva a implementar IFoo.Bar pueda IFoo.Bar sobre sí misma, no veo que haya ningún propósito útil para que la implementación explícita sea sellada .

Por cierto, en vb.net, el patrón normal simplemente sería Protected Overridable Sub IFoo_Bar() Implements IFoo.Bar , sin necesidad de un método virtual separado.