2011-08-09 11 views
14

Estoy configurando un código de demostración para una sesión de principiante sobre accesibilidad y descubrí que puedo acceder a una propiedad interna protegida desde una clase derivada. ¿Qué me estoy perdiendo?propiedad protegida interna aún accesible desde un ensamblaje diferente

Asamblea 1

namespace Accessibility 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      ExampleClass c = new ExampleClass(); 
      c.Go(); 
      //c.Prop1 = 10; 
     } 
    } 

    class ExampleClass : DerivedClass 
    { 
     public void Go() 
     { 
      this.Prop1 = 10; 
      this.Prop2 = 10; 
      //this.Prop3 = 10; //Doesn't work 
      //this.Prop4 = 10; //Doesn't work 
      this.Prop5 = 10; //why does this work?! 

      this.DoSomething(); 
     } 
    } 
} 

Asamblea 2

namespace Accessibility.Models 
{ 
    public class BaseClass 
    { 
     public int Prop1 { get; set; } 
     protected int Prop2 { get; set; } 
     private int Prop3 { get; set; } 

     internal int Prop4 { get; set; } 
     internal protected int Prop5 { get; set; } 
     //internal public int Prop6 { get; set; } //Invalid 
     //internal private int Prop7 { get; set; } //Invalid 

     public BaseClass() 
     { 
      this.Prop3 = 27; 
     } 
    } 

    public class DerivedClass : BaseClass 
    { 
     public void DoSomething() 
     { 
      this.Prop1 = 10; 
      this.Prop2 = 10; 
      //this.Prop3 = 10; //Doesn't work 
      this.Prop4 = 10; 
      this.Prop5 = 10; 

      PropertyInfo Prop3pi = typeof(DerivedClass).GetProperty("Prop3", BindingFlags.Instance | BindingFlags.NonPublic); 
      int value = (int)Prop3pi.GetValue(this, null); 
     } 
    } 
} 

Aviso en ExampleClass.Go puedo establecer un valor a Prop5. ¿Por qué? Está marcado como interno protegido pero no puedo establecer un valor en Prop4 (marcado como interno)

+16

Porque es * interno * O * protegido *. No AND. –

+1

-1: Obviamente, una simple búsqueda en Google habría respondido a esta pregunta ... –

+1

No pensé que era O –

Respuesta

20

internal protected significa "interno del conjunto O una clase heredada". Así que sí, si usted tiene una clase pública con un miembro interno protegido, otra clase que hereda ese tipo en un montaje distinto todavía puede acceder a él a causa de la modificador protected:

interna protegida

El tipo o Se puede acceder al miembro con cualquier código en el ensamblado en el que se declare, o desde dentro de una clase derivada en otro ensamblado.El acceso desde otro ensamblado debe tener lugar dentro de una declaración de clase que se deriva de la clase en la que se declara el elemento interno protegido, y debe tener lugar a través de una instancia del tipo de clase derivada.

Referencia: http://msdn.microsoft.com/en-us/library/ms173121.aspx

Ésta es una limitación del lenguaje C#. El CLR es compatible con la noción "interno y protegido". Hay evidencia de esto con la enumeración MethodAttributes.FamANDAssem si estaba emitiendo su propia IL. Si realmente quería esta característica, podría hacer algo de postprocesamiento IL con algo así como Mono.Cecil. Por qué el lenguaje C# no expone esto es solo una suposición: poca necesidad de hacerlo.

6

Porque así es como está diseñado internal protected. El acceso se da para los niños en el árbol de herencia (parte protected) o para el mismo conjunto (parte internal) - ver Access Modifiers on MSDN.

Y su ExampleClass está en el árbol de herencia de BaseClass, que define Prop5. Entonces el acceso es gracias a protected parte.

+0

me gusta la explicación simple. –

4

Al combinar las palabras clave protegidas e internas, un miembro de la clase puede marcarse como protegido interno: solo los tipos derivados o los tipos dentro del mismo ensamblado pueden acceder a ese miembro.

This MSDN article responde a todas sus preguntas.

+0

¿Es o no es la palabra clave más restringida? –

+0

Eso es correcto. Protegido interno significa que tanto los tipos derivados (protegidos) como el ensamblado (interno) pueden acceder a él. Eso solo se aplica al modificador interno. No puedes combinar otros. –

3

La palabra clave protected es un modificador de acceso de miembro. Se puede acceder a un miembro protegido desde dentro de la clase en la que se declara, y desde dentro de cualquier clase derivada de la clase que declaró este miembro.

http://msdn.microsoft.com/en-us/library/bcd5672a(v=vs.71).aspx

Mediante la combinación de las palabras clave protegidas e internas, un miembro de la clase pueden ser marcados interna protegida - tipos o sólo los tipos derivados dentro del mismo conjunto puede acceder a ese miembro.

http://msdn.microsoft.com/en-us/library/ms173121(v=vs.80).aspx

2

Protected significa que sólo se comparte con clases descendientes, solamente private significa que no se puede acceder por cualquier persona.

Editar: Hans hace su pregunta un poco más clara. Cuando combina modificadores como ese, se combinan inclusivamente no exclusivamente. Es accesse en todos los sentidos internal o protected puede ser.

0

Última respuesta, pero me atrapó con el mismo problema. Eventualmente, se me ocurrió una solución parcial.

internal Int MyInt 
    { 
     get; 
     protected set; 
    } 

Todavía es visible dentro del conjunto, pero al menos solo las clases heredadas pueden cambiarlo realmente. Es suficiente para lo que yo quería.

Cuestiones relacionadas