2012-05-18 9 views
9

(To pytanie jest kontynuacją C# accessing protected member in derived class)C chronione # dostęp pole

Mam następujący fragment kodu:

public class Fox 
{ 
    protected string FurColor; 
    private string furType; 

    public void PaintFox(Fox anotherFox) 
    { 
     anotherFox.FurColor = "Hey!"; 
     anotherFox.furType = "Hey!"; 
    } 
} 

public class RedFox : Fox 
{ 
    public void IncorrectPaintFox(Fox anotherFox) 
    { 
     // This one is inaccessible here and results in a compilation error. 
     anotherFox.FurColor = "Hey!"; 
    } 

    public void CorrectPaintFox(RedFox anotherFox) 
    { 
     // This is perfectly valid. 
     anotherFox.FurColor = "Hey!"; 
    } 
} 
  • Teraz wiemy, że private and protected fields are private and protected for type, not instance.

  • Wiemy również, że modyfikatory dostępu powinny działać podczas kompilacji.

  • Tak tu jest pytanie - dlaczego nie mogę uzyskać dostęp do pola instancji Fox klasy FurColor w RedFox?RedFox pochodzi z Fox, więc kompilator wie, że ma dostęp do odpowiednich pól chronionych.

  • Ponadto, jak widać w CorrectPaintFox, mogę uzyskać dostęp do chronionego pola instancji klasy RedFox. Dlaczego więc nie mogę oczekiwać tego samego z instancji klasy Fox?

+7

Istnieje [wpis na blogu autorstwa Erica Lipperta na ten temat] (http://blogs.msdn.com/b/ericlippert/archive/2005/11/09/491031.aspx). –

+1

Dlaczego? Ponieważ tak określono język: http://msdn.microsoft.com/en-us/library/aa691129 (v = vs.71) .aspx –

Odpowiedz

5

Proste powodem jest:

public void IncorrectPaintFox(Fox anotherFox) 
{ 
    anotherFox = new BlueFox(); 

    // This one is inaccessible here and results in a compilation error. 
    anotherFox.FurColor = "Hey!"; 
} 

Teraz nie masz dostępu do pola chroniony od wewnątrz BlueFox, dlatego ponieważ kompilator nie wie, co jest typ środowiska wykonawczego, musi zawsze popełnij błąd.

+0

@Cicada - dzięki, zaktualizowano –

+0

+1 osobom zawsze zapominamy o klasach rodzeństwa ... –

2

Aby rozwinąć nieco na zaakceptowanej odpowiedzi, powodem kompilator wymusza tej reguły, w przeciwieństwie do znacznie bardziej liberalne rozumieniu protected że PHP ma, to dlatego, umożliwiając dostęp chcesz zezwolić pozwoliłoby na zerwać niezmienniki klasy, pomijając zdefiniowane poziomy ochrony. (Oczywiście zawsze jest to możliwe, np. Za pomocą Reflection, ale kompilator co najmniej utrudnia wykonanie przez przypadek).

Problemem jest to, że po prostu wiedząc, że jakiś obiekt jest Fox nie czyni to bezpieczne, aby współdziałać z jego wewnętrznego działania, ponieważ nie może być rzeczywiścieFox na wykonywania. Następujące klasy:

public class Fox 
{ 
    protected Color FurColor; 
} 

public class RedFox 
{ 
    public RedFox() 
    { 
    this.FurColor = Color.Red; 
    } 
} 

public class ArcticFox 
{ 
    public ArcticFox() 
    { 
    this.FurColor = Color.White; 
    } 
} 

co prosicie jest dla kompilatora, aby umożliwić w następujący sposób, zakładając, że została zdefiniowana w klasie RedFox:

public void PaintFoxRed (Fox fox) 
{ 
    fox.FurColor = Color.Red; 
} 

Ale gdyby to było legalne, co mogłem zrobić to:

RedFox a = new RedFox(); 
Fox b = new ArcticFox(); 
a.PaintFoxRed(b); 

My ArcticFox jest teraz czerwony pomimo klasa sama tylko pozwala, by biały.

Powiązane problemy