5

I Created and implemented an interface explicitly as below.

public interface IA
{
    void Print();
}

public class C : IA
{
    void IA.Print()
    {
        Console.WriteLine("Print method invoked");
    }
}

and Then executed following Main method

public class Program
{
    public static void Main()
    {
        IA c = new C();
        C c1 = new C();
        foreach (var methodInfo in c.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance))
        {
            if (methodInfo.Name == "ConsoleApplication1.IA.Print")
            {
                if (methodInfo.IsPrivate)
                {
                    Console.WriteLine("Print method is private");
                }
            }
        }
        
        c.Print();
    }
}

and the result I got on console is:

Print method is private

Print method invoked

So my question is why this private method got executed from other class?

As far as I understand the accessibility of private member is restricted to its declaring type then why does it behave so strangely.

Community
  • 1
  • 1
Jenish Rabadiya
  • 6,708
  • 6
  • 33
  • 62

1 Answers1

6

So my question is why this private method got executed from other class?

Well, it's only sort-of private. It's using explicit interface implementation - it's accessible via the interface, but only via the interface. So even within class C, if you had:

C c = new C();
c.Print();

that would fail to compile, but

IA c = new C();
c.Print();

... that will work everywhere, because the interface is public.

The C# spec (13.4.1) notes that explicit interface implementation is unusual in terms of access:

Explicit interface member implementations have different accessibility characteristics than other members. Because explicit interface member implementations are never accessible through their fully qualified name in a method invocation or a property access, they are in a sense private. However, since they can be accessed through an interface instance, they are in a sense also public.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • So does that mean accessibility restriction only applies to references of object not to an Runtime instance? – Jenish Rabadiya Jun 03 '15 at 12:05
  • @JenishRabadiya No, it means that you can cast an object which implements the whole interface to that interface and Access that not that private member :D – Matías Fidemraizer Jun 03 '15 at 12:06
  • 1
    @JenishRabadiya: Not sure what you mean... but explicit interface implementation is "a bit odd" - I'll quote a bit of the spec. – Jon Skeet Jun 03 '15 at 12:06
  • @JonSkeet See my answer to OP comment... I believe he means that explicit implementations can be accessed during run-time, which isn't true: it can be accessed during compile-time casting the object to the interface which has explictly-implemented members. – Matías Fidemraizer Jun 03 '15 at 12:07
  • 1
    @JenishRabadiya I'm imagining that your next question may be "well, *why* would you want to do that?". In which case: http://stackoverflow.com/questions/4103300/why-implement-interface-explicitly – Matthew Watson Jun 03 '15 at 12:08
  • @JonSkeet Your quotes in updated answer makes sense to me that it's totally different scenario when you do work with explicit interface implementation. Thanks for your answer. – Jenish Rabadiya Jun 03 '15 at 12:11
  • 1
    As a side note, there are even more weird accessibility rules: http://stackoverflow.com/questions/22856215/what-is-the-meaning-of-the-planned-private-protected-c-sharp-access-modifier – Kryptos Jun 03 '15 at 12:16