From section 3.5 of the C# 4 spec:
Declarations of members allow control over member access. The accessibility of a member is established by the declared accessibility (§3.5.1) of the member combined with the accessibility of the immediately containing type, if any.
...
Access to a member is permitted when the textual location in which the access takes place is included in the accessibility domain (§3.5.2) of the member.
Then in section 3.5.2 (accessibility domains):
The accessibility domain of a nested member M declared in a type T within a program P is defined as follows (noting that M itself may possibly be a type):
- If the declared accessibility of M is public, the accessibility domain of M is the accessibility domain of T.
- ...
- If the declared accessibility of M is private, the accessibility domain of M is the program text of T.
This is the case here. So the accessibility domain of DoSomething
is the accessibility domain of PrivateInnerClass
by the first bullet... but the accessibility domain of PrivateInnerClass
is the program text of OuterClassBase
by the final bullet.
Therefore the call within OuterClassDerived
is not in the accessibility domain of DoSomething
, so it can't call it.
I'm actually surprised that you can derive ProtectedInnerClass
from PrivateInnerClass
in the first place...
EDIT: And it turns out you can't... even having removed the OuterClassDerived
class entirely, you get this error:
Test.cs(10,21): error CS0060: Inconsistent accessibility: base class
'OuterClassBase.PrivateInnerClass' is less accessible than class
'OuterClassBase.ProtectedInnerClass'
This violates section 10.1.4.1 of the specification:
The direct base class of a class type must be at least as accessible as the class type itself (§3.5.2). For example, it is a compile-time error for a public class to derive from a private or internal class.
Here you're trying to derive a protected class from a private class - the protected class is more accessible than the private class, hence the error.