Private Protected access likely comes back in C# 7.
My readers are likely familiar with the four access modifiers in C#: public, protected, internal, and private. Public access means accessible by any code. Protected access enables access for all derived classes. Internal access enables access from any code in the same assembly. Private access is limited to code in the same class. C# also supports “protected internal” access. Protected Internal access enables access from all code in the same assembly, and all derived classes.
What was missing was a more restrictive access: enable only code in the same assembly AND derived from this class to access those members. The CLR has supported this for some time, but it was not legal in C#. The team wanted to ad it in C# 6, using the keywords “private protected”. That generated a tremendous amount of feedback. While everyone liked the feature, there was a lot of negative feedback on the syntax. Well, after much discussion, thought, and experimentation, it’s back. It’s back with the same syntax.
Let’s explain some of the thinking behind this.
One overriding goal for the team was that this feature should not require a new keyword that could potentially break code. New keywords might be used in existing code as identifiers (variables, fields, methods, class names, and so on). In fact, the C# language design team has managed to avoid adding any new global keywords since C# 2.0. All the features for LINQ, dynamic, async and await, and more have been implemented using contextual keywords. Contextual keywords have special meaning only when used in a particular context. That enabled the language designers to add new features with less concern that they could be breaking existing code.
Using Contextual Keywords is very hard when you are talking about access modifiers. Remember that access modifiers are optional. Members of a class have a default access: private. Therefore, when the language parser looks at a method declaration, the first token may be an optional access modifier, ore it may be the return type. So, some new keyword for the new restrictive access would have the potential to break code: if some developer had created a type with the name of the proposed modifier, that code would break.
So, new keywords are out. That removes any suggestions like “protected or internal” and “protected and internal”. Those would be great suggestions, were it not for the breaking code problem.
However this feature was going to be implemented, it needed to use a combination of the current keywords. This new access is more restrictive than the current “protected internal” access. The modifier used should reflect that. The design question now becomes what combination of access modifier keywords would reflect a more restrictive access, and yet express that both internal and protected modifiers are in play?
Let’s reject out of hand the suggestion that the current ‘protected internal’ access should be repurposed for this feature, and a new combination of keywords used for the existing feature. That would break way too much code, and there’s no way for tools to know if you meant the old meaning, or the new meaning.
The other possible suggestion was to make “protected internal” have the current meaning, and make “internal protected” take on the new meaning. Well, that’s also a breaking change. In today’s world, you can type the ‘protected’ and ‘internal’ keywords in either order, and it has the same meaning. That fails the breaking change concern.
Of the possible combinations, “private protected” comes out best. Along with “private internal” it’s the only combination of 2 access modifiers that make sense, and isn’t already in use. One other option could be “private protected internal”, but that’s a lot of extra typing.
Overall, there are a lot of requests for adding the feature and enabling this accessibility. The proposed syntax is still the best way to express it. The language design team thought through alternatives, polled the community, and asked in public. This is still the best expression for this feature.
I’m glad it’s back.
All of these projects are Open Source (using the Creative Commons license for content, and the MIT license for code). If you would like to contribute, visit our GitHub Repository. Or, if you have questions, comments, or ideas for improvement, please create an issue for us.