Al intentar anular la implementación de interfaz explícita de la propiedad de la clase Collection<T>
, encontré algunos documentos que indican que las implementaciones explícitas de miembros de la interfaz no pueden anularse porque no pueden tener modificadores como virtual
o abstract
. En MSDN llegan incluso a especificar cómo hacer que una implementación de miembro de interfaz explícita esté disponible para la herencia creando otro miembro abstracto o virtual al que llama la implementación de miembro de interfaz explícita. Sin problemas hasta ahora.C#: sobrescritura de propiedades especificando la interfaz explícitamente
Pero entonces me pregunto: Por qué es posible en C# para anular cualquier miembro de interfaz implementada de manera explícita simplemente especificando la interfaz explícitamente?
Por ejemplo, supongamos que tengo una interfaz sencilla como esta, con una propiedad y método:
public interface IMyInterface
{
bool AlwaysFalse { get; }
bool IsTrue(bool value);
}
y una clase A
que implementa la interfaz de forma explícita, y tiene un método Test()
que llama a su propia interfaz implementación de miembro.
public class A : IMyInterface
{
bool IMyInterface.AlwaysFalse
{ get { return false; } }
bool IMyInterface.IsTrue(bool value)
{ return value; }
public bool Test()
{ return ((IMyInterface)this).AlwaysFalse; }
}
Como se puede ver, ninguno de los cuatro miembros son virtuales o abstractos, así que cuando me defino una clase B
así:
public class B : A
{
public bool AlwaysFalse
{ get { return true; } }
public bool IsTrue(bool value)
{ return !value; }
}
Entonces lo que espera una instancia de yeso para B
A
para comportarse como A
. Y lo hace:
A a = new A();
Console.WriteLine(((IMyInterface)a).AlwaysFalse); // False
Console.WriteLine(((IMyInterface)a).IsTrue(false)); // False
Console.WriteLine(a.Test()); // False
A b = new B();
Console.WriteLine(((IMyInterface)b).AlwaysFalse); // False
Console.WriteLine(((IMyInterface)b).IsTrue(false)); // False
Console.WriteLine(b.Test()); // False
Ahora viene la trampa. Crear una clase C
que es una copia exacta de B
excepto por una cosa en la declaración de clase:
public class C : A, IMyInterface
{ /* ... same as B ... */ }
Ahora una instancia de C
, cuando se convierte a A
, no se comportan como A
pero como C
:
A c = new C();
Console.WriteLine(((IMyInterface)c).AlwaysFalse); // True
Console.WriteLine(((IMyInterface)c).IsTrue(false)); // True
Console.WriteLine(c.Test()); // True
¡Incluso el método Test()
ahora llama al método anulado en C
! ¿Por qué es esto?
pregunta muy interesante! –