c# - que - poo
¿Por qué y cómo C#permite acceder a variables privadas fuera de la clase cuando está dentro de la misma clase contenedora? (3)
No sé si la pregunta es suficientemente descriptiva, pero ¿por qué y cómo existe este comportamiento ?:
public class Layer
{
public string Name { get; set; }
private IEnumerable<Layer> children;
public IEnumerable<Layer> Children
{
get { return this.children.Where ( c => c.Name != null ).Select ( c => c ); }
set { this.children = value; }
}
public Layer ( )
{
this.children = new List<Layer> ( ); // Fine
Layer layer = new Layer ( );
layer.children = new List<Layer> ( ); // Isn''t .children private from the outside?
}
}
Puedo acceder a layer.Children
cualquier lugar, está bien, pero ¿cómo puedo acceder a layer.children
ya que es privado?
Layer layer = new Layer ( );
layer.children = new List<Layer> ( );
solo funciona si el código está dentro de la clase Layer
. ¿Hay algún código especial para tratar el acceso a las variables privadas de forma diferente si se realiza dentro de la clase contenedora, aunque el acceso sea desde el exterior?
Sé la razón de usar:
this.children = ...
dentro de la clase contenedora, pero crear nuevas instancias y modificarlas desde el exterior, incluso si todavía están dentro de la clase contenedora, no parece una buena práctica.
¿Cuál es la razón para permitir esto?
Este es un diseño común. Se supone que quien escribió la clase sabe cómo trabajar con ella correctamente y entiende lo que significa tener acceso directo a miembros privados. Así que acceder a miembros privados de otras instancias de la misma clase a menudo funciona. Si está familiarizado con la construcción de friend
C ++, entonces es como si las instancias de la misma clase fueran todos amigos entre sí (aunque C # no tiene ninguna noción de friend
oficialmente).
Esto funciona en C # y Java, esos son los dos idiomas que conozco en la parte superior de mi cabeza. Apuesto a que muchos otros idiomas también permiten esto (¿alguien quiere entrar?)
Ver la sección 3.5.1 de la especificación del lenguaje C #. El texto relevante es este:
Privado, que se selecciona al incluir un modificador privado en la declaración del miembro. El significado intuitivo de privado es "acceso limitado al tipo que lo contiene".
Tenga en cuenta que el modificador es relevante para el tipo , no la instancia.
Y luego en la sección 3.5.2 algunas reglas se explican con más detalle:
En términos intuitivos, cuando se accede a un tipo o miembro M, se evalúan los siguientes pasos para garantizar que se permita el acceso:
- Primero, si M se declara dentro de un tipo (a diferencia de una unidad de compilación o un espacio de nombres), se produce un error en tiempo de compilación si no se puede acceder a ese tipo.
- Entonces, si M es público, el acceso está permitido.
- De lo contrario, si M está protegido internamente, se permite el acceso si se produce dentro del programa en el que se declara M, o si se produce dentro de una clase derivada de la clase en la que M se declara y se produce a través del tipo de clase derivada (§ 3.5.3).
- De lo contrario, si M está protegido, el acceso está permitido si se produce dentro de la clase en la que se declara M, o si se produce dentro de una clase derivada de la clase en la que M se declara y tiene lugar a través del tipo de clase derivada (§3.5 .3).
- De lo contrario, si M es interno, el acceso está permitido si ocurre dentro del programa en el que se declara M.
- De lo contrario, si M es privado, el acceso está permitido si ocurre dentro del tipo en el que se declara M.
- De lo contrario, el tipo o miembro es inaccesible y se produce un error en tiempo de compilación.
Recuerde, el modificador de acceso privado dice que los Private members are accessible only within the body of the class or the struct in which they are declared
. Esta descripción es confusa, pero dice claramente que la restricción está en el nivel de clase y NOT OBJECT LEVEL
. En este caso, la capa todavía está dentro de la clase.
Esto ha sido discutido aquí antes. podemos acceder a una variable privada usando un objeto