2009-12-02 6 views
11

Cela peut sembler plutôt une question débutante, mais pouvez-vous expliquer pourquoi la méthode Der.B() ne peut pas accéder à Foo protégé via la variable de classe Base? Cela me semble bizarre:Membres protégés C# accédés via la variable de classe de base

public class Base 
{ 
    protected int Foo; 
} 

public class Der : Base 
{ 
    private void B(Base b) { Foo = b.Foo; } // Error: Cannot access protected member 

    private void D(Der d) { Foo = d.Foo; } // OK 
} 

Merci!

Répondre

22

Cette question est fréquemment posée. Pour comprendre pourquoi cela est illégal, réfléchissez à ce qui pourrait mal tourner. Supposons que vous ayez une autre classe dérivée dérivée de Base. Vous passez maintenant une instance de Frob à Der.B. Devriez-vous être en mesure d'accéder à Frob.Foo à partir de Der.B? Non, absolument pas. Frob.Foo est protégé; il ne devrait être accessible qu'à partir de Frob et des sous-classes de Frob. Der n'est pas Frob et n'est pas une sous-classe de Frob, donc il n'a pas accès aux membres protégés de Frob.

Si ce n'est pas clair, voir mon article sur le sujet:

http://blogs.msdn.com/ericlippert/archive/2005/11/09/491031.aspx

+0

Merci. C'est clair pour moi maintenant. – Roman

0

Dans le scénario que vous essayez, vous voudrez utiliser "internal" pour int Foo.

+1

Ce ne sera pas travailler si B est passé une base pas un Der. –

+0

Je sais que je peux utiliser interne ou même public au lieu de protégé. Mais je veux comprendre pourquoi la protection se comporte comme décrit dans le post. – Roman

+2

@Roman: car protégé n'est visible que par la classe Dérivée. Dans la même instance. Mais vous essayez de le regarder à partir d'une instance différente. Si cela pouvait être fait, la protection serait pratiquement inutile. –

4

En B, vous essayez d'accéder à un membre protégé d'une autre classe. Le fait que vous héritiez de cette classe n'est pas pertinent. En D, vous accédez à un membre protégé de la classe de base de votre classe actuelle. Dans ce contexte, vous pouvez accéder à n'importe quoi depuis Der et les membres protégés du type dont il hérite.

+0

+ 1 pour explication, mais je doute encore que "le fait que vous héritiez de cette classe n'est pas pertinent"? Est-ce le prédicat de la spécification? – Roman

+0

Le fait que vous en héritiez vous donne accès à celui-ci si quelqu'un initialise un Der. Dans ce cas, vous pouvez le convertir en Der et ensuite accéder à Foo. –

2

Dit simplement, protégé permet l'accès aux sous-classes.

Dans:

private void B(Base b) { Foo = b.Foo; } 

Vous essayez d'accéder à un membre protégé votre instance de Der n'a pas accès. Il n'y aurait accès que s'il s'agissait de la classe de base de votre instance actuelle de Der (this).

private void D(Der d) { Foo = d.Foo; } // OK 

fonctionne très bien parce que vous traversez Der pour accéder à ses classes de base Méthode protégée.

+1

Je pense que vous vouliez dire: privé vide D (Der d) {Foo = d.Foo; } Fonctionne bien. Un peu déroutant b/c vous avez dupliqué la ligne de code. – Doug

+0

Woops, ouais je voulais copier le deuxième exemple de code. – Ragepotato

2

Vous pouvez contourner cette limitation en déclarant une méthode statique dans la classe de base:

public class Base 
{ 
    protected int Foo; 

    protected static int GetFoo(Base b) 
    { 
     return b.Foo; 
    } 
} 

public class Der : Base 
{ 
    private void B(Base b) { Foo = GetFoo(b); } // OK 
}
Questions connexes