Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class implementing interfaces with conflicting method signatures

Tags:

c#

interface

clr

Let's say we have two interfaces with conflicting method signatures:

interface IA
{
    void F();
}

interface IB
{
    int F();
}

and now we create a class like this:

class Test : IA, IB
{
    public void F() { ... }
    int IB.F() { ... }
}

The method named as IB.F looks like a private method, however you can do something like this:

var t = new Test();
t.F();       //Calls public method F
((IB)t).F(); //Calls private method IB.F!!!

So my question is: how does the C# compiler know that IB.F can be called outside the class scope?

I guess it's that IB. prefix, but looked into the IL code and it just appears as a private method with that odd signature.

like image 312
ecampver Avatar asked May 31 '13 18:05

ecampver


2 Answers

The "private" method contains the following:

.method private hidebysig newslot virtual final instance int32 ns.IB.F() cil managed
{ 
    .override Tests.IB::F
    //...
}

And in IB:

.method public hidebysig newslot abstract virtual instance int32 F() cil managed
{
}

The .override tells the compiler to have a look at the declaration in IB. There it says that the method is public.

The method is not actually declared private, "nothing" means public for interface methods by default.

Try adding any kind of access modifier in front of int IB.F(), it will be a compiler error, because you may not change the accessibility of explicit interface implementations.

like image 66
pascalhein Avatar answered Oct 13 '22 00:10

pascalhein


A method that looks like

int IB.F() { ... }

i.e. there is a dot . in its name and the part of the name before the (last) dot is an interface name, is not an ordinary instance method. It is a so-called explicit interface implementation.

Do not think of it as a usual private method. Note that it is not even legal to use the C# keyword private together with an explicit interface implementation.

In a sense, this method has the accessibility of the interface it implements.

So it can be called whenever someone has an instance of that class which is cast to the interface.

As an example, on the MSDN site they do not document internal or private members of classes. But they do document explicit interface implementation (where the interface is visible outside the assembly), because these members can be called from the outside (i.e. by us). See List<T> Class for an example.

like image 24
Jeppe Stig Nielsen Avatar answered Oct 13 '22 00:10

Jeppe Stig Nielsen