2010-03-03 20 views
21

Il s'agit d'un extension pour cette question il y a une heure.prioritaire protégé interne avec protégé!

Nous ne pouvons pas modifier le access modifiers, lors du remplacement d'un virtual method dans la classe derived. Envisager Control classe dans System.Web.UI espace de noms

public class Control : IComponent, IDisposable,... 
{ 
    protected internal virtual void CreateChildControls() 
    { } 
    . 
    . 
} 

Considérons maintenant Ce

public class someClass : System.Web.UI.Control 
    { 
     // This should not compile but it does 
     protected override void CreateChildControls() 
     { } 

     // This should compile but it does not 
     protected internal override void CreateChildControls() 
     { } 
    } 

tout organisme peut expliquer cela? Merci

Répondre

43

Nous ne pouvons pas modifier les modificateurs d'accès lors du remplacement d'une méthode virtuelle dans une classe dérivée.

Cette affirmation est fausse. Vous pouvez et changer les modificateurs d'accès dans exactement la situation que vous décrivez. Dans d'autres situations, vous ne devez pas modifier les modificateurs d'accès.

Je vous renvoie à l'article 10.6.4 du cahier des charges, qui stipule:

une déclaration de remplacement ne peut pas changer l'accessibilité de la méthode virtuelle. Cependant, si la méthode de base est substituée interne et il est protégé déclaré dans un autre assemblage que l'assemblage contenant la méthode de remplacement a alors déclaré la méthode de substitution l'accessibilité doit être protégé.

Le raisonnement est simple.

Vous, Asad, avez un compte bancaire, BankAccount.

Vous avez une maison. Vous louez une chambre dans la maison à votre meilleur ami Charlie.

Charlie a un fils, David, qui vit dans un appartement.

Vous avez un fils, Elroy, qui vit dans un condo. Elroy a un fils, votre petit-fils, Frank, qui vit dans une yourte. Elroy a un meilleur ami Greg qui vit dans le condo avec lui.

Vous accordez l'accès à votre compte bancaire à vous-même, à toute personne résidant à la maison et à l'un de vos descendants. Ainsi, les personnes qui peuvent accéder au compte bancaire sont Asad, Charlie, Elroy et Frank. David n'a pas accès parce qu'il n'est ni vous, ni votre descendant, ni qu'il vit à la maison. Qu'il est un enfant de votre colocataire n'est pas pertinent; il n'a pas accès à votre compte bancaire.

Greg n'a pas non plus accès à votre compte bancaire. Il n'est pas votre descendant. Il ne vit pas à la maison. Le fait qu'il vit avec votre descendant ne lui accorde pas les mêmes droits que votre descendant.

Maintenant, nous arrivons au cœur de la question. Elroy n'est pas autorisé à étendre l'accès à votre compte bancaire à Greg. Vous possédez ce BankAccount, et vous avez dit "moi-même, mes descendants et mes colocataires". Vos enfants n'ont pas le droit d'étendre l'accessibilité de BankAccount au-delà de ce que vous avez initialement défini. Quand Elroy décrit l'accès qu'il a à BankAccount, il est seulement autorisé à dire "J'accorde l'accès à ceci à moi-même et à mes descendants", parce que c'est ce que vous avez déjà permis. Il ne peut pas dire "Je donne accès à BankAccount à moi-même, à mes descendants et aux autres résidents de Condo".

Pour être clair:

  • I et mes descendants obtenir l'accès = accès protégé
  • I et mes camarades de maison obtenir l'accès = accès interne
  • I et mes descendants et mes camarades de maison avoir accès = protégé accès interne
  • contrôle = Asad
  • CreateChildControls = BankAccount
  • Maison = System.web.dll
  • Charlie = tout type dans System.web.dll
  • David = type de Charlie dérivé dans l'assemblage Apartment.DLL
  • Elroy = someClass
  • Condo = votre assemblage contenant SomeClass
  • Greg = une autre classe dans Condo.DLL
  • Frank = type dérivé de someClass dans Yurt.DLL
  • Yurt = un autre ensemble
+0

Donc dans cette situation, que se passe-t-il lorsque le colocataire d'un parent essaie d'accéder à ce qu'il pense être le compte bancaire du parent, mais c'est en fait le compte bancaire d'un enfant? IE: Quelque chose dans System.Web.DLL essaie d'appeler Control.CreateChildControls() (via l'accessibilité interne), mais n'a pas accès à someClass.CreateChildControls()? – Tanzelax

+1

Bonne analogie ... sauf que je ne donnerais pas accès à mon compte bancaire à tout le monde vivant dans ma maison;) –

+5

@Eric, analogie intéressante. Une pensée - peut-être changer de * "qui peut accéder à mon compte bancaire" * à * "qui peut conduire ma voiture" * peut faire que l'analogie résonne mieux avec les gens. – LBushkin

5

Parce que, tandis que la terminologie est différente, l'ignorer protected conserve la même visibilité du membre. Si vous étiez autorisé à le remplacer par protected internal, vous exposeriez soudainement le membre à un autre type dans votre assembly.

+0

Downvot e soin d'expliquer? –

2

Protégé interne signifie protégé OU interne. Donc, si en surchargeant l'assembly d'origine, vous étiez autorisé à marquer l'interne protégé, vous autorisez d'autres classes dans le même assembly que le overrider à appeler cette méthode. Cela signifierait effectivement que l'encapsulation interne du parent original serait violée.