136

As part of the Roslyn documentation on GitHub, there's a page called Language feature implementation status, with planned language features for C# and VB.

One feature I couldn't wrap my head around was private protected access modifier:

private protected string GetId() { … } 

There is also a page of C# Language Design Notes, which explains many new features, but not this one.

Eric Lippert said in a comment:

Your error is in thinking of the modifiers as increasing restrictions. The modifiers in fact always decrease restrictions. Remember, things are "private" by default; only by adding modifiers do you make them less restricted.

What is the meaning of private protected? When might I use it?

Kobi
  • 135,331
  • 41
  • 252
  • 292
  • 2
    Note that there is information about it under the [VB language design notes](https://roslyn.codeplex.com/discussions/540509). – Jesse Good Apr 04 '14 at 08:13
  • 3
    It is a mapping to MethodAttributes.FamANDAssem. C# has a strange mapping of *internal*, it uses (Private|FamANDAssem). And *internal protected* maps to (Private|Family). The CLR attributes are weird. – Hans Passant Apr 04 '14 at 09:39
  • 22
    This proposed feature will make my comment incorrect. – Eric Lippert Apr 04 '14 at 15:54
  • The C# design team has published a [survey with suggested alternative syntax](https://www.surveymonkey.com/s/8YHQPGF) for this feature. Some of these are interesting, like `protected & internal`, `assembly protected` or `proternal` (I hope some of these are jokes). There is also the [Discussion thread](https://roslyn.codeplex.com/discussions/541194) with some nice insights. – Kobi May 01 '14 at 10:40
  • 1
    Feature is now marked withdrawn in the Language Feature implementation status! Personally I like the idea of this access level and I think its a useful feature. I want to use the protected to keep my code according to the class design, but I don't want others to write hacky sublasses that get access to this members. IMO the best solution would be if we could write `protected | internal` and `protected & internal` – Felix Keil Aug 14 '14 at 08:39

6 Answers6

195

Here are all access modifiers in Venn diagrams, from more limiting to more promiscuous:

private:
enter image description here

private protected: - added in C# 7.2
enter image description here

internal:
enter image description here

protected:
enter image description here

protected internal:
enter image description here

public:
enter image description here

Kobi
  • 135,331
  • 41
  • 252
  • 292
  • 3
    Source image: [Access Modifiers.pdn](https://www.dropbox.com/s/0uqi1ydxlqovvc9/Access%20Modifiers.pdn). I used the aptly named [Paint.Net](http://www.getpaint.net/). – Kobi Apr 09 '14 at 09:44
  • 9
    Where have these diagrams been all my (C#) life? They are excellent - thank you! – Jon Peterson May 08 '14 at 19:41
98

According to "Professional C# 2008" by De Bill Evjen and Jay Glynn, page 1699:

private protected - "only derived types within the current assembly"

C++/CLI has a similar feature - Define and Consume Classes and Structs (C++/CLI) > Member visibility:

private protected -or- protected private - Member is protected inside the assembly but private outside the assembly.

Kobi
  • 135,331
  • 41
  • 252
  • 292
Gogutz
  • 2,005
  • 17
  • 19
  • 75
    So it's "protected *and* internal" instead of "protected *or* internal"? – user541686 Apr 04 '14 at 08:16
  • 2
    Will now be possible to have a member which is accessible to derived classes accept or return things of `internal` type without requiring the member to be itself exposed to everything in the assembly? – supercat Apr 04 '14 at 15:53
  • Thanks! I didn't think about that. I actually has cases I would have used that modifier, and fell back on `internal`. – Kobi Apr 04 '14 at 18:40
  • 3
    The existence of this proposal/feature seems to suggest that `internal` visibility (related to where the class is defined) is really orthogonal to `public`/`protected`/`private` visibility (related to inheritance) and that, perhaps, `internal` should be its own modifier separate from `public`/`protected`/`private`. – jpmc26 Apr 04 '14 at 19:10
28

This is just to provide a graph (made with http://ashitani.jp/gv/) of the different accessibility levels (images do not fit in comments).

digraph diagram of C# access levels

Each arrow means "is more restrictive than".

The CLR names are Private, FamilyANDAssembly, Assembly, Family, FamilyORAssembly, Public.


Much later edit: It turned out this nice new access level (with a really poor name) was not eventually included in C# 6.0. It is supported only from C# 7.2 (and I see you updated your question "tags").

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
  • It might just be me, but the arrows seem to be going in the 'less restrictive than' direction. – acarlon Apr 08 '14 at 21:27
  • 4
    @acarlon Yes, so `a → b` in the diagram means "`a` is more restrictive than `b`", so you can "read" the arrow as "is more restrictive than" (that was what I tried to explain), so the arrow points in the least restrictive "direction". The opposite convention for the arrows could have been just as good, by the way, but I had to choose one convention. – Jeppe Stig Nielsen Apr 08 '14 at 22:13
10

It's just a guess, but from a name you could possibly guess it's a more restricted version of protected, (or more relaxed version of private if you wish). And only reasonable variant of it is restricting protected behaviour to assembly.

Possible usage: then you want to have protected for internal implementation, but not for external uses (and you don't want sealing the class).

P.S. It always existed in CLR, but not in C#. It's a combination of protected and internal, quote:

CLR also supports “Family and assembly” access type. This means that the method is accessible from within the declaring type, nested and derived types but only if they’re declared in the same assembly. Well, apparently C# team didn’t think of this as a very useful feature so it’s not supported in this language.

Petr Abdulin
  • 33,883
  • 9
  • 62
  • 96
  • +1 for the CLR comment - I spend so much time in C# and so little in the other .NET languages these days that I sometimes forget they are not the same thing. – brichins Apr 09 '14 at 00:15
  • @DarrelHoffman thanks for noting! I mixed up my thoughts here a bit) – Petr Abdulin Jul 30 '15 at 04:11
5

"May be" only visible to subclasses that are in same assembly. This makes it a little restricted than protected.

Mehmet Ataş
  • 11,081
  • 6
  • 51
  • 78
1

See the spec for the "private protected" feature:

The intuitive meaning of private protected is “accessible within this assembly by types derived from the containing class”.

Julien Couvreur
  • 4,473
  • 1
  • 30
  • 40