I have A.Test() declared as public virtual and B.Test() declared as private new.
I'm calling base.Test() from C that inherits B.
This code compiles with Mono 2.10.2 but throws a MethodAccessException:
class A {
public virtual void Test () { }
}
class B : A {
private new void Test () { }
}
class C : B {
public C ()
{
base.Test ();
}
public static void Main (string[] args)
{
var c = new C ();
}
}
Here is the exception I get:
System.MethodAccessException: Method TestBug.B:Test () is inaccessible from method TestBug.C:.ctor ()
Is this the correct behavior?
Does this compile in Microsoft .NET or with newer versions of Mono?
What does C# spec say about this?
Does it vary with C# version?
It's valid C#, but the Mono 2.10.2 compiler is apparently doing the wrong thing. With the MS compiler, the call to
base.Test()is compiled to:The Mono 3.0.6.0 compiler works the same way.
As far as
Ais concerned,B.Test()effectively doesn't exist.In fact, section 3.7 of the C# 5 spec even gives an explicit example which is very similar to yours:
I strongly suspect that the Mono 2.10.2 is blindly inserting a call to
B.Test()- not because it sees the private method's existence, but just to ensure that "a base class method is called". As it happens, that goes badly at execution time. The choice about which base class method to call is an interesting one, asBcould change between C's compile-time and execution time, to overrideTest()... at which point the behaviour is non-obvious. Eric Lippert talks about this in a blog post which you may find interesting.