una propiedades propiedad programacion metodos concepto clase automaticos accesores c# properties readonly

programacion - propiedades del c#



Cómo implementar una propiedad de solo lectura (6)

Con la introducción de C # 6 (en VS 2015), ahora puede tener propiedades solo automáticas de get , en las que el campo de respaldo implícito es de readonly (es decir, los valores pueden asignarse en el constructor pero no en otra parte):

public string Name { get; } public Customer(string name) // Constructor { Name = name; } private void SomeFunction() { Name = "Something Else"; // Compile-time error }

Y ahora también puede inicializar las propiedades (con o sin un configurador) en línea:

public string Name { get; } = "Boris";

Refiriéndose a la pregunta, esto le brinda las ventajas de la opción 2 (el miembro público es una propiedad, no un campo) con la brevedad de la opción 1.

Desafortunadamente, no proporciona una garantía de inmutabilidad en el nivel de la interfaz pública (como en el punto de @ CodesInChaos sobre la autodocumentación), porque para un consumidor de la clase, no tener un establecedor es indistinguible de tener un definidor privado.

Necesito implementar una propiedad de solo lectura en mi tipo. Además, el valor de esta propiedad se establecerá en el constructor y no se cambiará (estoy escribiendo una clase que expone los comandos de IU enrutados personalizados para WPF, pero no importa).

Veo dos maneras de hacerlo:

  1. class MyClass { public readonly object MyProperty = new object(); }

  2. class MyClass { private readonly object my_property = new object(); public object MyProperty { get { return my_property; } } }

Con todos estos errores de FxCop que dicen que no debería tener variables de miembro público, parece que el segundo es la forma correcta de hacerlo. ¿Correcto?

¿Hay alguna diferencia entre una propiedad de obtener solo y un miembro de solo lectura en este caso?

Agradecería cualquier comentario / consejo / etc.


El segundo método es preferido debido a la encapsulación. Ciertamente, puede hacer que el campo de solo lectura sea público, pero eso va en contra de los modismos de C # en los que tiene acceso a datos a través de propiedades y no de campos.

El razonamiento detrás de esto es que la propiedad define una interfaz pública y si la implementación de respaldo a esa propiedad cambia, no terminará rompiendo el resto del código porque la implementación está oculta detrás de una interfaz.


Estoy de acuerdo en que la segunda forma es preferible. La única razón real para esa preferencia es la preferencia general de que las clases .NET no tengan campos públicos. Sin embargo, si ese campo es de solo lectura, no puedo ver cómo habría objeciones reales que no sean la falta de coherencia con otras propiedades. La diferencia real entre un campo de solo lectura y una propiedad de obtener solo es que el campo de solo lectura proporciona una garantía de que su valor no cambiará durante la vida útil del objeto y una propiedad de obtener solo no.


La segunda forma es la opción preferida.

private readonly int MyVal = 5; public int MyProp { get { return MyVal;} }

Esto asegurará que MyVal solo pueda asignarse en la inicialización (también se puede configurar en un constructor).

Como ha señalado, de esta manera no está exponiendo a un miembro interno, lo que le permite cambiar la implementación interna en el futuro.


Puedes hacerlo:

public int Property { get { ... } private set { ... } }


Versiones:
Creo que no hace mucha diferencia si solo está interesado en la compatibilidad de fuentes.
Usar una propiedad es mejor para la compatibilidad binaria, ya que puede reemplazarla por una propiedad que tenga un configurador sin romper el código compilado, dependiendo de su biblioteca.

Convención:
Estás siguiendo la convención. En casos como este, donde las diferencias entre las dos posibilidades son relativamente menores, es mejor seguir la convención. Un caso en el que podría volver a morderte es el código basado en la reflexión. Es posible que solo acepte propiedades y no campos, por ejemplo, un editor / visor de propiedades.

Publicación por entregas
Cambiar de campo a propiedad probablemente romperá muchos serializadores. Y AFAIK XmlSerializer solo serializa propiedades públicas y no campos públicos.

Usando una Autoproperty
Otra variación común es usar una propiedad automática con un configurador privado. Si bien esto es corto y una propiedad no impone la readonlyness. Así que prefiero los otros.

El campo de solo lectura es autodocumentación
Sin embargo, hay una ventaja del campo:
De un vistazo a la interfaz pública, queda claro que en realidad es inmutable (salvo la reflexión). Mientras que en el caso de una propiedad, solo puede ver que no puede cambiarla, por lo que debería consultar la documentación o la implementación.

Pero para ser honesto, uso el primero con bastante frecuencia en el código de la aplicación, ya que soy perezoso. En las bibliotecas normalmente soy más detallista y sigo la convención.

C # 6.0 agrega propiedades de auto de solo lectura

public object MyProperty { get; }

Por lo tanto, cuando no necesita admitir compiladores más antiguos, puede tener una propiedad verdaderamente de solo lectura con un código tan conciso como un campo de solo lectura.