protected internal:
The union of protected and internal accessibility (this is less restrictive than protected or internal alone)
The CLR has the concept of intersection of protected and internal accessibility, but C# does not support this.
So my question is:
What's the meaning of omitting this Access Modifier, is there a concrete reason? So why C# should not support it?
The intersection of
protected
andinternal
would downgrade to a simpleinternal
for code external to your library – meaning it would not accessible, whether from derived classes or otherwise.As such, the only benefit a
protected internal intersection
would serve is for disciplining yourself, as the developer of your library, not to access the type/member except from the same or derived classes within your library. It will not make any difference for consumers of your library, since its semantics would be identical to a plaininternal
.That said, I would not have found it unreasonable for it to be allowed in C#. Self-discipline often comes in useful; it is the reason why the language designers differentiated between
private
andinternal
, despite the two being identical for external consumers.However, since the distinction between the intersection and the plain
internal
is small, they probably chose to exclude it in order to mitigate the risk of developers confusing it with the more-usefulprotected internal
union.Wrong question. The question should be "why should C# support
protected and internal
?"Keep in mind, the natural state of a feature is for it to not be implemented. Implementing a feature is very expensive in terms of resources, testing, and, let's not forget, opportunity cost (meaning it displaces other features). So to overcome this expense, there had better be an extremely clear benefit for implementing a feature that overcomes these costs.
In particular, what is the value of
protected and internal
? There really is no good reason to restrict accessibility only to derived classes in the same assembly.IMO it's odd the CLR supports it, but it does. That doesn't mean that C# needs to though.
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:
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 useprotected 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 theEditorBrowsableAttribute
ofNever
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 :)
You can always do:
As long as you do not let any external consumer instantiate the object what would you care if they try deriving it? Short answer, the feature you request brings nothing new and you already have tools to do what you are requesting.
It was a design decision, but consider what it means:
This is not a very useful boundary, I can't think of a clear use-case.
And that's why it probably wasn't worth coming up with a new keyword(-combination).
I would rather ask why the CLR supports it. Orthogonality I suppose.
As far as I know you can use intersection of protected and internal access modifiers but not with the interpretation you want (maybe because of what Henk said):
Protected: The type or member can only be accessed by code in the same class or struct, or in a derived class.
Internal: The type or member can be accessed by any code in the same assembly, but not from another assembly.
Protected Internal: The type or member can be accessed by any code in the same assembly, or by any derived class in another assembly.