Why its possible to override explicit implementation?

337 Views Asked by At

We usually implement interfaces explicitly when it’s not right to access interface member directly from implementer class. Weather it has to be internal or it causes conflicts with API design or when it increases the chance of misusing methods.

Implementing members individually for multiple interfaces with different logic is absolutely discouraged in my mind so that’s not case here

Compiler does not allow making such implementation as virtual because it doesn't make sense and I think it’s right. Usually explicit implementation is very sensitive and that’s why you try to hide it.

However I found following way of over-riding explicit implementation (it’s not exactly override but its cheating alternative)

I found this surprising and quite disappointing. My question is why following code is allowed and works perfectly? I expected to get error that interface is already implemented explicitly.

This is just basic example to reproduce problem

static void Main(string[] args)
{
    var b = new Base();
    ((IInterface)b).Write();

    var c = new Child();
    ((IInterface)c).Write();
}
public interface IInterface
{
    void Write();
}
public class Base : IInterface
{
    void IInterface.Write()
    {
        Console.WriteLine("Base");
    }
}
public class Child : Base, IInterface // hack is here. Re Implemented :/
{
    void IInterface.Write()
    {
        Console.WriteLine("Child");
    }
}

Outputs

    Base
    Child
2

There are 2 best solutions below

3
On BEST ANSWER

why following code is allowed and works perfectly?

Because the specs say so:

It is a compile-time error for an explicit interface member implementation to include access modifiers, and it is a compile-time error to include the modifiers abstract, virtual, override, or static.

Yet in polymorphism, the saying goes "the more derived type knows better", from the specs again:

derived classes can extend and specialize base classes

So the most derived type who implements that interface explicitly will be called when you invoke that interface member.

0
On

I suggest you to think at the low level translation from C# into native code: the interface inheritance redeclaration, and the one or more of its methods overriding, forces rewriting of the VMT - Virtual Method Table (interface methods are virtual by design).