Quelle est la signification du modificateur d'accès C # «private protected» prévu?

133

Dans le cadre de la documentation Roslyn sur GitHub, il existe une page intitulée Statut de l'implémentation de la fonctionnalité de langage , avec des fonctionnalités de langage prévues pour C # et VB.

Une fonctionnalité sur laquelle je ne pouvais pas comprendre était le private protectedmodificateur d'accès:

private protected string GetId() {  } 

Il existe également une page de notes de conception du langage C # , qui explique de nombreuses nouvelles fonctionnalités, mais pas celle-ci.

Eric Lippert a déclaré dans un commentaire :

Votre erreur est de considérer les modificateurs comme des restrictions croissantes. Les modificateurs diminuent en fait toujours les restrictions. Souvenez-vous que les choses sont "privées" par défaut; ce n'est qu'en ajoutant des modificateurs que vous les rendez moins restreints.

Quelle est la signification de private protected? Quand pourrais-je l'utiliser?

Kobi
la source
2
Notez qu'il existe des informations à ce sujet dans les notes de conception du langage VB .
Jesse Good
3
Il s'agit d'un mappage vers MethodAttributes.FamANDAssem. C # a un étrange mappage interne , il utilise (Private | FamANDAssem). Et des cartes internes protégées vers (Privé | Familial). Les attributs CLR sont bizarres.
Hans Passant
22
Cette fonctionnalité proposée rendra mon commentaire incorrect.
Eric Lippert
L'équipe de conception C # a publié une enquête avec des suggestions de syntaxe alternative pour cette fonctionnalité. Certains d' entre eux sont intéressants, comme protected & internal, assembly protectedou proternal(j'espère que certains d' entre eux sont des blagues). Il y a aussi le fil de discussion avec quelques informations intéressantes.
Kobi
1
La fonctionnalité est désormais marquée comme retirée dans l'état de mise en œuvre de la fonctionnalité linguistique! Personnellement, j'aime l'idée de ce niveau d'accès et je pense que c'est une fonctionnalité utile. Je veux utiliser le protected pour conserver mon code selon la conception de la classe, mais je ne veux pas que d'autres écrivent des sous-classes de piratage qui ont accès à ces membres. IMO la meilleure solution serait si nous pouvions écrire protected | internaletprotected & internal
Felix Keil

Réponses:

98

D'après " Professional C # 2008 " de De Bill Evjen et Jay Glynn, page 1699:

private protected - "uniquement les types dérivés dans l'assembly actuel"

C ++ / CLI a une fonctionnalité similaire - Définir et consommer des classes et des structures (C ++ / CLI)> Visibilité des membres :

private protected-ou-- protected private- Le membre est protégé à l'intérieur de l'assembly mais privé à l'extérieur de l'assembly.

Gogutz
la source
72
Donc c'est «protégé et interne» au lieu de «protégé ou interne»?
user541686
2
Sera-t-il désormais possible d'avoir un membre accessible aux classes dérivées qui accepte ou renvoie des choses de internaltype sans exiger que le membre soit lui-même exposé à tout dans l'assembly?
supercat le
Merci! Je n'y ai pas pensé. J'ai en fait des cas sur lesquels j'aurais utilisé ce modificateur et sur lesquels je me suis rabattu internal.
Kobi
3
L'existence de cette proposition / fonctionnalité semble suggérer que la internalvisibilité (liée à l'endroit où la classe est définie) est vraiment orthogonale à public/ protected/ privatevisibilité (liée à l'héritage) et que, peut-être, internaldevrait être son propre modificateur distinct de public/ protected/ private.
jpmc26
1
@jww - Je ne connais pas très bien Java, mais autant que je sache packageen Java, cela ressemble plus à un espace de noms en C #.
Gogutz
187

Voici tous les modificateurs d'accès dans les diagrammes de Venn, du plus limitatif au plus promiscuité:

private:
entrez la description de l'image ici

private protected: - ajouté en C # 7.2
entrez la description de l'image ici

internal:
entrez la description de l'image ici

protected:
entrez la description de l'image ici

protected internal:
entrez la description de l'image ici

public:
entrez la description de l'image ici

Kobi
la source
3
Image source: Access Modifiers.pdn . J'ai utilisé le bien nommé Paint.Net .
Kobi
9
Où ces diagrammes ont-ils été toute ma vie (C #)? Ils sont excellents - merci!
Jon Peterson
28

Il s'agit simplement de fournir un graphique (réalisé avec http://ashitani.jp/gv/ ) des différents niveaux d'accessibilité (les images ne rentrent pas dans les commentaires).

diagramme digraph des niveaux d'accès C #

Chaque flèche signifie "est plus restrictif que".

Les noms CLR sont Private, FamilyANDAssembly, Assembly, Family, FamilyORAssembly, Public.


Edition beaucoup plus tardive: il s'est avéré que ce nouveau niveau d'accès sympa (avec un nom vraiment médiocre) n'a finalement pas été inclus dans C # 6.0. Il est pris en charge uniquement à partir de C # 7.2 (et je vois que vous avez mis à jour votre question "tags").

Jeppe Stig Nielsen
la source
C'est peut-être juste moi, mais les flèches semblent aller dans la direction «moins restrictive que».
acarlon
4
@acarlon Oui, donc a → bdans le diagramme signifie " aest plus restrictif que b", donc vous pouvez "lire" la flèche comme "est plus restrictive que" (c'est ce que j'ai essayé d'expliquer), donc la flèche pointe dans le moins restrictif " direction". La convention inverse pour les flèches aurait pu être tout aussi bonne, au fait, mais j'ai dû choisir une convention.
Jeppe Stig Nielsen
10

C'est juste une supposition, mais à partir d'un nom que vous pourriez probablement deviner, c'est une version plus restreinte de protected, (ou une version plus détendue de privatesi vous le souhaitez). Et la seule variante raisonnable de celui-ci est de restreindre le protectedcomportement à l'assemblage.

Utilisation possible: alors vous voulez avoir protectedpour l'implémentation interne, mais pas pour des utilisations externes (et vous ne voulez pas sceller la classe).

PS Il a toujours existé en CLR, mais pas en C # . C'est une combinaison de protected et internal , citation:

CLR prend également en charge le type d'accès «Famille et assemblage». Cela signifie que la méthode est accessible depuis le type déclarant, les types imbriqués et dérivés, mais uniquement s'ils sont déclarés dans le même assembly. Eh bien, apparemment, l'équipe C # ne considérait pas cela comme une fonctionnalité très utile, donc ce n'est pas pris en charge dans ce langage.

Petr Abdulin
la source
+1 pour le commentaire CLR - Je passe tellement de temps en C # et si peu dans les autres langages .NET ces jours-ci que j'oublie parfois qu'ils ne sont pas la même chose.
brichins
@DarrelHoffman merci d'avoir noté! J'ai un peu mélangé mes pensées ici)
Petr Abdulin
5

"Peut être" uniquement visible pour les sous-classes qui sont dans le même assemblage. Cela le rend un peu restreint protected.

Mehmet Ataş
la source
1

Voir la spécification de la fonctionnalité "protection privée":

La signification intuitive de private protected est «accessible dans cet assembly par des types dérivés de la classe contenant».

Julien Couvreur
la source