2009-12-02 4 views
11

Es scheint eher Neuling Frage, aber können Sie erklären, warum Methode Der.B() kann nicht zugreifen geschützt Foo über Base-Klasse-Variable? Das sieht mir komisch aus:C# protected Mitglieder zugegriffen über Basisklassenvariable

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 
} 

Danke!

Antwort

22

Dies ist eine häufig gestellte Frage. Um herauszufinden, warum dies illegal ist, überlegen Sie, was schiefgehen könnte.

Angenommen, Sie hätten eine andere abgeleitete Klasse Frob von Base abgeleitet. Nun übergeben Sie eine Instanz von Frob an Der.B. Solltest du von Der.B aus auf Frob.Foo zugreifen können? Nein auf keinen Fall. Frob.Foo ist geschützt; es sollte nur von Frob und Unterklassen von Frob zugänglich sein. Der ist nicht Frob und ist keine Unterklasse von Frob, also bekommt er keinen Zugang zu den geschützten Mitgliedern von Frob.

Wenn das nicht klar ist, meine Artikel zu diesem Thema finden Sie unter:

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

+0

Vielen Dank. Es ist mir jetzt klar. – Roman

0

In dem Szenario, das Sie versuchen, möchten Sie "internal" für Int Foo verwenden.

+1

Dies wird nicht arbeite, wenn B eine Base nicht einen Der übergeben wird. –

+0

Ich weiß, dass ich intern oder sogar öffentlich statt geschützt verwenden kann. Aber ich möchte verstehen, warum sich geschütztes Verhalten wie in der Post beschrieben verhält. – Roman

+2

@Roman: Da protected nur für die Derived-Klasse sichtbar ist. In derselben Instanz. Aber Sie versuchen, es von einer anderen Instanz aus zu betrachten. Wenn das getan werden könnte, wäre geschützt ziemlich nutzlos. –

4

In B versuchen Sie, auf ein geschütztes Mitglied einer anderen Klasse zuzugreifen. Die Tatsache, dass Sie von dieser Klasse erben, ist irrelevant. In D greifen Sie auf ein geschütztes Mitglied der Basisklasse Ihrer aktuellen Klasse zu. In diesem Kontext können Sie auf alles von Der und den geschützten Elementen des Typs zugreifen, von dem es erbt.

+0

+1 für die Erklärung, aber ich bezweifle immer noch, warum "die Tatsache, dass Sie von dieser Klasse erben ist irrelevant"? Ist es Spezifikationsprädikat? – Roman

+0

Die Tatsache, dass Sie davon erben, gibt Ihnen Zugriff darauf, wenn jemand einen Der initialisiert. In diesem Fall könntest du es auf Der übertragen und dann auf Foo zugreifen. –

2

Einfach gesagt, geschützt ermöglicht den Zugriff auf Unterklassen.

In:

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

Sie versuchen, ein geschütztes Mitglied Instanz von Der muss nicht auf dem Zugriff zuzugreifen. Es hätte nur Zugriff darauf, wenn es die Basisklasse der aktuellen Instanz von Der (Dies) wäre.

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

Funktioniert gut, weil Sie Der gehen, um auf seine Basisklassen geschützte Methode zuzugreifen.

+1

Ich glaube, du wolltest sagen: private void D (Der d) {Foo = d.Foo; } Funktioniert gut. Ein wenig verwirrend b/c dupliziert die Codezeile. – Doug

+0

Woops, ja ich wollte das zweite Codebeispiel kopieren. – Ragepotato

2

Sie können durch die Deklaration eine statische Methode in der Basisklasse um diese Einschränkung umgehen:

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 
}