2012-05-18 50 views
9

(Esta pregunta es un seguimiento de C# accessing protected member in derived class)C# acceso protegido campo

he el siguiente fragmento de código:

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!"; 
    } 
} 
  • Ahora, sabemos que private and protected fields are private and protected for type, not instance.

  • También sabemos que los modificadores de acceso deberían funcionar en tiempo de compilación.

  • lo tanto, aquí es la cuestión - por qué no puedo acceder al campo de la instancia de la clase FoxFurColor en RedFox?RedFox se deriva de Fox, por lo que el compilador sabe que tiene acceso a los campos protegidos correspondientes.

  • Además, como puede ver en CorrectPaintFox, puedo acceder al campo protegido de la instancia de clase RedFox. Entonces, ¿por qué no puedo esperar lo mismo de la instancia de clase Fox?

+7

Hay una [publicación de blog de Eric Lippert sobre ese tema] (http://blogs.msdn.com/b/ericlippert/archive/2005/11/09/491031.aspx). –

+1

¿Por qué? Porque así es como se especificó el idioma: http://msdn.microsoft.com/en-us/library/aa691129 (v = vs.71) .aspx –

Respuesta

5

razón es simple:

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

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

Ahora usted no está accediendo a la zona protegida desde dentro BlueFox, por lo tanto, ya que el compilador no sabe qué tipo de tiempo de ejecución es, tiene que siempre hacer esto un error

+0

@Cicada - gracias, actualizado –

+0

+1 personas siempre se olvidan de las clases de hermanos ... –

2

Para ampliar un poco en la respuesta aceptada, la razón el compilador hace cumplir esta regla, en contraposición al significado mucho más laxa de protected que PHP tiene, se debe permitir el acceso que desea permitir que haría posible romper las invariantes de una clase, al eludir sus niveles de protección definidos. (Por supuesto, esto siempre es posible, por ejemplo, a través de Reflection, pero el compilador al menos hace que sea difícil hacer por accidente).

El problema es que el hecho de saber que un objeto es un Fox no significa que sea seguro para que usted pueda interactuar con su funcionamiento interno, porque no puede ser en realidad un Fox en tiempo de ejecución. Tenga en cuenta estas clases:

public class Fox 
{ 
    protected Color FurColor; 
} 

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

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

lo que están pidiendo es para el compilador que permita el siguiente método, suponiendo que se definió en la clase RedFox:

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

Pero si eso fuera legal, que podría hacer esto:

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

Mi ArcticFox es ahora de color rojo a pesar de la propia clase única dejándose blanco.

Cuestiones relacionadas