The "protected" keyword means that only a type and types that derive from that type can access the member. D has no relationship to C therefore cannot access the member.
You have a couple of options if you want to be able to access that member
- Make it public
- Make it internal. This will allow any types to access the member within the same assembly (or other assemblies should you add friend's)
- Derive D from C
EDIT
This scenario is called out in section 3.5.3 of the C# spec.
The reason this is not allowed is because it would allow for cross hierarchy calls. Imagine that in addition to D, there was another base class of C called E. If your code could compile it would allow D to access the member E.F. This type of scenario is not allowed in C# (and I believe the CLR but I don't 100% know).
EDIT2 Why this is bad
Caveat, this is my opinion
The reason this is now allowed is it makes it very difficult to reason about the behavior of a class. The goal of access modifiers is to give the developer control over exactly who can access specific methods. Imagine the following class
sealed class MyClass : C {
override F(D d) { ... }
}
Consider what happens if F is a somewhat time critical function. With the current behavior I can reason about the correctness of my class. After all there are only two cases where MyClass.F will be called.
- Where it's invoked in C
- Where I explicitly invoke it in MyClass
I can examine these calls and come to a reasonable conclusion about how MyClass functions.
Now, if C# does allow cross hierarchy protected access I can make no such guarantee. Anyone in a completely different assembly can come by and derive from C. Then they can call MyClass.F at will. This makes it completely impossible to reason about the correctness of my class.