Quelle est la différence entre «protégé» et «protégé interne»?

244

Quelqu'un peut-il m'expliquer la différence entre les modificateurs «protégés» et «protégés internes» en C #? Il semble qu'ils se comportent de la même manière.

Embedd_Khurja
la source

Réponses:

402

Le modificateur d'accès "interne protégé" est une union des modificateurs "protégé" et "interne".

Depuis MSDN, modificateurs d'accès (Guide de programmation C #) :

protégé :

Le type ou le membre n'est accessible que par du code dans la même classe ou structure, ou dans une classe dérivée de cette classe.

interne :

Le type ou le membre est accessible par n'importe quel code du même assembly, mais pas à partir d'un autre assembly.

interne protégé :

Le type ou le membre est accessible par n'importe quel code de l'assembly dans lequel il est déclaré, OU à partir d'une classe dérivée dans un autre assembly. L'accès à partir d'un autre assembly doit avoir lieu dans une déclaration de classe qui dérive de la classe dans laquelle l'élément interne protégé est déclaré, et il doit avoir lieu via une instance du type de classe dérivée.

Notez que : protected internalsignifie " protectedOU internal" (toute classe du même assembly ou toute classe dérivée - même si elle se trouve dans un assembly différent).

... et pour être complet:

privé :

Le type ou le membre n'est accessible que par du code dans la même classe ou structure.

public :

Le type ou le membre est accessible par tout autre code du même assembly ou par un autre assembly qui le référence.

privé protégé :

L'accès est limité à la classe conteneur ou aux types dérivés de la classe conteneur dans l'assembly actuel.
( Disponible depuis C # 7.2 )

M4N
la source
2
Puis-je avoir un membre protected internalpour qu'il soit protecteddans l'assemblage actuel et complètement indisponible en externe?
Shimmy Weitzhandler du
8
Ce serait «protégé», n'est-ce pas?
CAD bloke
2
@Shimmy: vous pouvez avoir une classe interne avec des méthodes protégées . Mais alors la classe entière ne sera pas disponible à partir des assemblys externes.
M4N
1
@Shimmy jetez un œil à cette proposition pour une future version de C # github.com/dotnet/roslyn/blob/features/privateProtected/docs/…
Nate Cook
@Shimmy Au moins CLR prend en charge le concept de l'intersection de l'accessibilité protégée et interne, mais pas le langage C #. C # ne prend en charge que l'union des deux modificateurs d'accès.
RBT
89

protected peut être utilisé par n'importe quelle sous-classe de n'importe quel assemblage.

protected internalest tout ce qui protectedest, et aussi tout ce qui se trouve dans le même assemblage peut y accéder.

Surtout, cela ne signifie pas «sous-classes dans le même assemblage» - c'est l'union des deux, pas l'intersection.

Marc Gravell
la source
3
Juste une info pour les lecteurs que CLR prend également en charge le concept de l'intersection de l'accessibilité protégée et interne, mais C # ne le prend pas en charge. C # ne prend en charge que l'union des deux, comme mentionné dans cet article.
RBT
1
Juste un autre info pour les lecteurs, "des sous-classes dans le même assemblage" peuvent être obtenues avec le private protectedmodificateur d'accès qui a été introduit dans C # 7.2
LordWilmore
52

- Mettre à jour la réponse 2019 -

Vous pouvez trouver la différence dans l'accessibilité basée sur le tableau ci-dessous: oui,

entrez la description de l'image ici

Andi AR
la source
4
Belle réponse, elle communique très clairement les différences entre chaque modificateur d'accès.
e_i_pi
23

En pratique, sur les méthodes:

protected - accessible pour les classes héritées, sinon privée.

interne - public uniquement pour les classes à l'intérieur de l'assembly, sinon privé.

protected internal - signifie que les méthodes protected ou internal - deviennent accessibles pour les classes héritées et pour toutes les classes à l'intérieur de l'assembly.

abatishchev
la source
1
J'utiliserais OR pour exprimer cette cause, ce n'est pas les deux qui doit être vrai.
Brian Rasmussen
Je ne suis pas entièrement d'accord avec la partie "pour changer le comportement de la classe de base" dans la description de "protégé". Je dirais que c'est là que vous utilisez "virtuel" (sur la classe de base) et "remplacer" (sur la classe dérivée).
M4N
Existe-t-il un moyen de marquer un membre comme protectedET internal?
Shimmy Weitzhandler du
@Shimmy: oui, protected internal.
abatishchev
1
@Shimmy deux ans plus tard, et oui. Maintenant, il existe un moyen en C # 7.2. Son appelé private protected docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
Pauli Østerø
10

Il y a encore beaucoup de confusion dans la compréhension de la portée des accesseurs "internes protégés", bien que la plupart aient la définition correctement définie. Cela m'a aidé à comprendre la confusion entre «protégé» et «protégé interne»:

public est vraiment public à l'intérieur et à l'extérieur de l'assemblée ( public interne / public externe )

protected est vraiment protégée à l'intérieur et à l'extérieur de l'assemblage ( protégé interne / protégé externe ) (non autorisé sur les classes de niveau supérieur)

private est vraiment privé à l'intérieur et à l'extérieur de l'assembly ( private internal / private external ) (non autorisé sur les classes de niveau supérieur)

interne est vraiment public à l'intérieur de l'assembly mais exclu en dehors de l'assembly comme privé ( public interne / exclu externe )

interne protégé est vraiment public à l'intérieur de l'assembly mais protégé à l'extérieur de l'assembly ( public interne / externe protégé ) (non autorisé sur les classes de niveau supérieur)

Comme vous pouvez le voir, l' intérieur protégé est une bête très étrange. Pas intuitif.

Cela soulève maintenant la question de savoir pourquoi Microsoft n'a pas créé un ( protégé interne / externe exclu ), ou je suppose une sorte de "privé protégé" ou "interne protégé"? lol. Semble incomplet?

À la confusion s'ajoute le fait que vous pouvez imbriquer des membres imbriqués internes publics ou protégés dans des types protégés, internes ou privés. Pourquoi voudriez-vous accéder à un "interne protégé" imbriqué à l'intérieur d'une classe interne qui exclut l'accès d'assembly externe?

Microsoft dit que ces types imbriqués sont limités par leur portée de type parent, mais ce n'est pas ce que le compilateur dit. Vous pouvez compiler des internes protégés dans des classes internes, ce qui devrait limiter la portée à l'assembly uniquement.

Pour moi, cela ressemble à une conception incomplète. Ils devraient avoir simplifié la portée de tous les types à un système qui considère clairement l'héritage mais aussi la sécurité et la hiérarchie des types imbriqués. Cela aurait rendu le partage d'objets extrêmement intuitif et granulaire plutôt que de découvrir l'accessibilité des types et des membres sur la base d'un système de cadrage incomplet.

Stokely
la source
1
private protected a maintenant été ajouté à C # 7.2 qui est fondamentalement interne ET protégé.
Pauli Østerø
7

protected : la variable ou la méthode ne sera disponible que pour les classes enfants (dans n'importe quel assembly)

interne protégé : disponible pour les classes enfants dans n'importe quel assembly et pour toutes les classes dans le même assembly

Benjamin
la source
3

J'ai lu des définitions très claires de ces termes.

Protégé: l'accès est limité à la définition de classe et à toute classe qui hérite de la classe. Le type ou le membre n'est accessible que par du code dans la même classe ou structure ou dans une classe dérivée de cette classe.

Interne: l'accès est limité à exclusivement aux classes définies dans l'assembly de projet en cours. Le type ou le membre est accessible uniquement par le code de la même classe.

Protected-Internal: l'accès est limité à l'assembly actuel ou aux types dérivés de la classe contenante.

Ammar Asjad
la source
1

Membre protégé

Membre protégé d'une classe disponible uniquement dans la classe contenue (dans laquelle il a été déclaré) et dans la classe dérivée au sein de l'assembly et également en dehors de l'assembly.

Signifie si une classe qui réside en dehors de l'assembly peut utiliser le membre protégé de l'autre assembly en héritant uniquement de cette classe.

Nous pouvons exposer le membre protégé en dehors de l'assembly en héritant de cette classe et l'utiliser uniquement dans la classe dérivée.

Remarque: Les membres protégés ne sont pas accessibles à l'aide de l'objet dans la classe dérivée.

Membre interne

Un membre interne d'une classe est disponible ou accessible au sein de l'assembly, soit en créant un objet, soit dans une classe dérivée, ou vous pouvez dire qu'il est accessible dans toutes les classes de l'assembly.

Remarque: Les membres internes ne sont pas accessibles en dehors de l'assembly à l'aide de la création d'objets ou dans une classe dérivée.

Interne protégé

Le modificateur d'accès interne protégé est une combinaison protégée ou interne.

Le membre interne protégé peut être disponible dans l'assembly entier dans lequel il a déclaré créer un objet ou hérité de cette classe. Et peut être accessible en dehors de l'assembly dans une classe dérivée uniquement.

Remarque: Le membre interne protégé fonctionne comme interne dans le même assemblage et fonctionne comme protégé pour l'extérieur de l'assembly.

Mostafa Bouzari
la source
1

public - Les membres (fonctions et variables) déclarés comme publics sont accessibles de n'importe où.

privé - Les membres privés ne sont pas accessibles depuis l'extérieur de la classe. Il s'agit du spécificateur d'accès par défaut pour un membre, c'est-à-dire que si vous ne spécifiez pas de spécificateur d'accès pour un membre (variable ou fonction), il sera considéré comme privé. Par conséquent, chaîne PhoneNumber; est équivalent à la chaîne privée PhoneNumber.

protected - Les membres protégés ne sont accessibles que depuis les classes enfants.

interne - Il n'est accessible que dans le même assemblage.

protégé interne - Il est accessible dans le même assemblage ainsi que dans la classe dérivée.

Piush shukla
la source
0

Protéger les meilleures suites internes lorsque vous souhaitez qu'un membre ou un type soit utilisé dans une classe dérivée d'un autre assembly en même temps que vous souhaitez simplement consommer le membre ou le type dans l'assembly parent sans dériver de la classe où il est déclaré. De plus, si vous souhaitez uniquement utiliser un membre ou un type sans dériver d'une autre classe, dans le même assembly, vous ne pouvez utiliser que interne.

satishpkumarine
la source