-1

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
M.kazem Akhgary
  • 18,645
  • 8
  • 57
  • 118
  • How did you manage to mess up the code formatting like that? – CodeCaster Sep 05 '17 at 12:19
  • Consider a bit more complicated case, the method `Write` should print all internal variables of the class. Now if `Child` had more variables then surely it should re-implement the interface since it could contain more variables than the `Base`. Can't see your point of preventing re-implementation of interfaces. – T.Aoukar Sep 05 '17 at 12:20
  • @CodeCaster i typed it from my phone. I sent text containing code from my pc to my phone, and then copy pasted. SO wasnt happy with my copy paste. – M.kazem Akhgary Sep 05 '17 at 12:22
  • 1
    `// hack is here. Re Implemented :/` What makes you think it is a hack? `Child` explicitly says it implements `IInterface` - and the compiler sees an implementation declared right there. Why **wouldn't** it use that one? – mjwills Sep 05 '17 at 12:23
  • 1
    _"Why its possible to override explicit implementation?"_ Why _wouldn't_ it be? What if I'm also implementing `IOtherInterface` that _also_ has a `Write` method. I have to use explicit implementation then, but my child classes need to do something different. – James Thorpe Sep 05 '17 at 12:24
  • @mjwills if you design an API, you make class inheritable so it can be extended. But sure you dont want others to misuse it. I can not make interface internal because its from uwp library – M.kazem Akhgary Sep 05 '17 at 12:26
  • 2
    There is simply no way to achieve what you want @M.kazemAkhgary. If the class implements a public interface then, by definition, it is allowed to **actually** implement it. – mjwills Sep 05 '17 at 12:28

2 Answers2

2

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.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • That make sense, i didn't see in your perspective. Is there any way to prevent this? Assuming you are designing an API and you cant make interface internal. – M.kazem Akhgary Sep 05 '17 at 12:28
  • 4
    Mark `class Base` as sealed. If you're just exposing interfaces for an API, not classes, you can't control how developers are going to use it. – CodeCaster Sep 05 '17 at 12:30
  • I see, but i wanted it to be inheritable so it can be extended. I guess what i want cant be achieved. I could allow use of wrapper class instead or use internal fields. Thanks for the answer. – M.kazem Akhgary Sep 05 '17 at 12:32
0

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).

Antonio Petricca
  • 8,891
  • 5
  • 36
  • 74