c# - protegidas - ¿Qué es mejor entre un modificador de solo lectura y un configurador privado?
modificador internal c# (5)
Con el inicializador de propiedades automáticas de C # 6.0 , hay menos manera de hacerlo
private readonly string productLocation;
public string ProductLocation { get { return productLocation; } }
Cual es
public string ProductLocation { get; }
Esto es de solo lectura. Solo inicializado desde constructor o en linea. No se puede editar después de la inicialización. (Inmutable desde cualquier lugar)
Sin embargo, si usas set privado;
public string ProductLocation { get; private set }
Esto es solo de afuera. Pero se puede inicializar en cualquier momento en cualquier lugar dentro de la misma clase. Y puede ser editado dentro de su ciclo de vida por la propia clase. (Mutable de clase, inmutable de fuera)
He estado trabajando en la creación de una clase y de repente se me ocurrió una idea de cuál es la diferencia entre los dos códigos:
public readonly string ProductLocation;
Y
public string ProductLocation
{
get;
private set;
}
¿Pueden darme una idea de cuándo usar mejor lo siguiente? Gracias.
El primero (usando readonly
) significará que el objeto ni siquiera puede modificar el valor de su propio campo , una vez que el objeto ha sido instanciado, y otros nunca pueden modificarlo.
El segundo (usando private set
) significará que el objeto puede modificar el valor de su campo después de que se haya creado una instancia, pero otros nunca pueden modificarlo.
Yo usaría lo primero para algo que usted sabe que no cambiará , y lo último para algo donde el valor puede cambiar, pero no quiere que otros lo cambien.
El primero es un campo cuyo valor solo se puede establecer en la instanciación .
La segunda es una propiedad cuyo valor se puede establecer en cualquier momento (pero solo por su objeto contenedor).
Corrección: la propiedad se puede establecer en cualquier momento por cualquier instancia de la misma clase (y no solo por su objeto contenedor).
El primero es un campo de solo lectura, mientras que el segundo se compila como un par de métodos (y todas las lecturas de la propiedad ProductLocation
se compilan en llamadas al método get
correspondiente y las escrituras se compilan en llamadas al método set
; internamente, estos métodos leerán / escribirán en un campo interno, generado automáticamente, no de solo lectura). Yo diría que la diferencia más importante es la seguridad de los hilos . (¿Cómo? Sigue leyendo!)
El uso básico de la clase se verá exactamente igual: el código de otras clases solo podrá leer el valor, no cambiarlo. Además, el código para leer el valor se verá exactamente igual (por ejemplo, print(myInstace.ProductLocation)
; aquí, no puede saber cómo se ha declarado, genial, ¿eh?)
La primera diferencia, la más trivial, es que la propiedad con establecedor privado permite que las instancias de la misma clase modifiquen el valor, mientras que en el caso de la propiedad de solo lectura, ni siquiera el propio objeto podrá cambiar el valor.
Ahora, por la seguridad del hilo. El atributo de readonly
en el campo cambiará su semántica de visibilidad de la memoria cuando esté trabajando con varios subprocesos (al igual que los campos final
de Java).
Un campo de solo readonly
solo se puede asignar a una declaración o en el constructor. El valor asignado a un campo de readonly
no se puede cambiar (al menos no de manera normal ) y se garantiza que cada subproceso verá el valor inicializado correctamente después de que el constructor regrese . Por lo tanto, un campo de readonly
es intrínsecamente seguro para subprocesos.
Para lograr la misma seguridad de subprocesos con la propiedad, tendría que agregar algo de sincronización en su código, que es propenso a errores. Puede llevar a bloqueos, carreras de datos o rendimiento reducido, según el caso, y especialmente si no tiene experiencia.
Entonces, si el valor representa algo que no puede modificarse semánticamente después de la construcción del objeto, no debe declarar un establecedor privado (esto implicaría que el objeto podría cambiarlo). Vaya al campo de solo lectura (y tal vez lo declare privado y declare una propiedad pública con solo un captador accediendo al campo. Esta es la forma preferida, ya que no es bueno exponer campos, es mejor solo exponer los métodos, allí Hay muchas razones para explicar por qué en esta respuesta )
En general, no se recomienda en .NET exponer públicamente los campos de los miembros, estos deben ser envueltos por una propiedad. Asumamos que puedes tener
private readonly string productLocation;
public string ProductLocation { get { return productLocation; } }
vs
public string ProductLocation { get; private set; }
En esta configuración, e ignorando lo que uno podría lograr mediante la reflexión, la semántica es que en el primer caso, la variable productLocation
solo puede inicializarse en el lugar y en el constructor de la clase. Otros miembros de la clase no pueden alterar el valor. Los consumidores externos no tienen la capacidad de establecer el valor.
En la segunda versión, los consumidores externos siguen sin tener acceso para establecer el valor. Sin embargo, la clase en sí puede cambiar el valor en cualquier momento. Si todo lo que tiene es un DTO (es decir, una clase que solo transporta datos, no tiene lógica expresada a través de métodos), entonces esto esencialmente no es tan diferente de la versión de readonly
. Sin embargo, para las clases con métodos, esos métodos podrían alterar el valor detrás de ProductLocation
.
Si desea aplicar el concepto de un campo inmutable después de la construcción, use readonly
. Pero para un DTO, podría ir para el private set;
Opción, principalmente porque es menos código repetitivo.