I wanted to ask this same question, but thankfully SO found this one for me.
I can understand the point of view that it would require either at least a new keyword, or new semantics for existing keywords, so it wasn't supported because the cost-benefit didn't work in its favour.
However, I question whether it's legitimate to avoid implementing this CLR feature because of the narrow use-case or because it could confuse people.
One argument given above is that it's only use would be to enforce self-discipline.
But then the same could be said of any visibility modifier that isn't public
. The idea, also, that it would only apply to 'a single developer of a single library' is plainly erroneous, too. Many libraries are developed by teams of people, and it's entirely natural for a developer within that team to add a member that he or she would want to restrict only to internal types derived from his or her base.
Then there's this scenario:
internal class Foo {
}
public class PublicBase {
protected Foo MyFoo { get; set; }
}
In the case here, I have an internal type that I want to expose on a class, but I only want to expose it to derived types. Since the type is internal, that implicitly means derived types in the same assembly. External types can still legitimately inherit from this type, but they won't need to use this member.
In this situation I'm stuck: I can't use protected
, nor can I use protected internal
.
Instead, I have to use internal
, which incorrectly broadcasts to other members of my team that it should be used from code outside the class. Sure I can stick a comment on it (and even stick the EditorBrowsableAttribute
of Never
on it, but that would hide it from internal inheritors too) - but it's not the same.
As it is, the only way I can achieve this is to hack the assembly with an IL rewrite after the build - but I need this visibility (or lack of it) at compile-time, not after it's built.
Ultimately, arguments about "what keyword(s) would it use" or "how would it be implemented" are irrelevant to me: I'm the programmer, not the C# language designer.
Equally, I have to say arguments like "Well, protected internal
is confusing enough for many" are also irrelevant. There are so many developers I've come into contact with, either in person or virtually, who don't understand things like ?:
or generic constraints - guess what, they don't use them! That doesn't mean I shouldn't.
So yes I understand the reasons for not implementing it - but I disagree with them - therefore my answer for why C# doesn't support it is because the C# designers got it wrong.
And yes I'm ready for the heat that might bring to my door :)