While attempting to override the explicit interface implementation of the ICollection<T>.IsReadOnly
property from the Collection<T>
class, I came across some documents stating that explicit interface member implementations cannot be overridden because they cannot have modifiers such as virtual
or abstract
. On MSDN they even go as far as specifying how to make an explicit interface member implementation available for inheritance by creating another abstract or virtual member which is called by the explicit interface member implementation. No problems so far.
But then I wonder: Why is it possible in C# to override any explicitly implemented interface member just by specifying the interface explicitly?
For example, suppose I have a simple interface like this, with a property and method:
public interface IMyInterface
{
bool AlwaysFalse { get; }
bool IsTrue(bool value);
}
And a class A
which implements the interface explicitly, and has a method Test()
which calls its own interface member implementation.
public class A : IMyInterface
{
bool IMyInterface.AlwaysFalse
{ get { return false; } }
bool IMyInterface.IsTrue(bool value)
{ return value; }
public bool Test()
{ return ((IMyInterface)this).AlwaysFalse; }
}
As you can see, none of the four members are virtual or abstract, so when I define a class B
like this:
public class B : A
{
public bool AlwaysFalse
{ get { return true; } }
public bool IsTrue(bool value)
{ return !value; }
}
Then you'd expect an instance of B
cast to A
to behave like A
. And it does:
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
Now comes the catch. Create a class C
which is an exact copy of B
except for one thing in the class declaration:
public class C : A, IMyInterface
{ /* ... same as B ... */ }
Now an instance of C
, when cast to A
, doesn't behave like A
but like C
:
A c = new C();
Console.WriteLine(((IMyInterface)c).AlwaysFalse); // True
Console.WriteLine(((IMyInterface)c).IsTrue(false)); // True
Console.WriteLine(c.Test()); // True
Even the Test()
method now calls the overridden method in C
! Why is this?