Me acabo de dar cuenta de que la construcción de la propiedad C # también se puede usar con un modificador de acceso privado :
private string Password { get; set; }
Aunque esto es técnicamente interesante, no puedo imaginar cuándo lo usaría, ya que un campo privado implica aún menos ceremonia :
private string _password;
y no puedo imaginar cuándo necesitaría poder obtener internamente pero no establecer o establecer pero no obtener un campo privado:
private string Password { get; }
o
private string Password { set; }
pero tal vez haya un caso de uso con clases anidadas / heredadas o tal vez donde un get / set pueda contener lógica en lugar de simplemente devolver el valor de la propiedad, aunque tendería a mantener las propiedades estrictamente simples y dejar que los métodos explícitos hagan cualquier lógica, por ej GetEncodedPassword()
.
¿Alguien usa propiedades privadas en C # por alguna razón o es solo una de esas construcciones de código técnicamente posibles pero raramente usadas en el código real?
Apéndice
Buenas respuestas, al leerlas, seleccioné estos usos para propiedades privadas:
- cuando los campos privados necesitan ser cargados perezosamente
- cuando los campos privados necesitan lógica adicional o son valores calculados
- ya que los campos privados pueden ser difíciles de depurar
- para "presentar un contrato a ti mismo"
- convertir / simplificar internamente una propiedad expuesta como parte de la serialización
- envolviendo variables globales para ser utilizadas dentro de su clase
fuente
Respuestas:
Los uso si necesito almacenar en caché un valor y quiero cargarlo de forma diferida.
fuente
return _password ?? (_password = CallExpensiveOperation());
return _password ?? (_password = CallExpensiveOperation());
una sola línea desde hace un tiempo. O en realidad Resharper lo prefiere :).private string Password => _password ?? (_password = CallExpensiveOperation());
private string Password => _password ??= CallExpensiveOperation();
CallExpensiveOperation();
se llama durante la construcción / inicialización del objeto contenedor y no cuando se accede por primera vez a la propiedad.El uso principal de esto en mi código es la inicialización diferida, como otros han mencionado.
Otra razón para las propiedades privadas sobre los campos es que las propiedades privadas son mucho más fáciles de depurar que los campos privados. Con frecuencia quiero saber cosas como "este campo se está configurando inesperadamente; ¿quién es la primera persona que llama que configura este campo?" y es mucho más fácil si solo puedes poner un punto de interrupción en el setter y presionar ir. Puedes poner el registro allí. Puede poner métricas de rendimiento allí. Puede realizar comprobaciones de coherencia que se ejecutan en la compilación de depuración.
Básicamente, todo se reduce a: el código es mucho más poderoso que los datos . Cualquier técnica que me permita escribir el código que necesito es buena. Los campos no le permiten escribir código en ellos, las propiedades sí.
fuente
Yo personalmente uso esto incluso cuando no necesito lógica en el captador o definidor de una propiedad. El uso de una propiedad, incluso privada, ayuda a proteger su código a futuro para que pueda agregar la lógica a un getter más adelante, si es necesario.
Si siento que una propiedad eventualmente puede requerir lógica adicional, a veces la envolveré en una propiedad privada en lugar de usar un campo, para no tener que cambiar mi código más tarde.
En un caso semi-relacionado (aunque diferente a su pregunta), uso muy frecuentemente los setters privados en propiedades públicas:
Esto te da un captador público, pero mantiene al setter privado.
fuente
Un buen uso para las propiedades privadas de obtención solo son valores calculados. Varias veces he tenido propiedades que son privadas de solo lectura y solo hago un cálculo sobre otros campos en mi tipo. No es digno de un método y no es interesante para otras clases, por lo que es propiedad privada.
fuente
La inicialización diferida es un lugar donde pueden estar limpios, p. Ej.
Luego puede escribir: en
this.MyType
todas partes en lugar dethis.mytype.Value
y encapsular el hecho de que se crea una instancia perezosa en un solo lugar.Una cosa que es una pena es que C # no admite el alcance del campo de respaldo a la propiedad (es decir, declararlo dentro de la definición de la propiedad) para ocultarlo por completo y garantizar que solo se pueda acceder a él a través de la propiedad.
fuente
field-declaration
s examinado dentroaccessor-declarations
ha clasificado el número 1 en mi lista de deseos de C # durante mucho tiempo. Si pudieras lograr que se diseñara e implementara en alguna versión futura (real), entonces te prepararé un pastel.El único uso que se me ocurre
fuente
private bool IsPasswordSet() { return !String.IsNullOrEmpty(_password); }
Las propiedades y los campos no son uno a uno. Una propiedad se trata de la interfaz de una clase (ya sea hablando de su interfaz pública o interna), mientras que un campo se trata de la implementación de la clase. Las propiedades no deben verse como una forma de exponer los campos, sino que deben verse como una forma de exponer la intención y el propósito de la clase.
Al igual que utiliza propiedades para presentar un contrato a sus consumidores sobre lo que constituye su clase, también puede presentarse un contrato a usted mismo por razones muy similares. Entonces sí, uso propiedades privadas cuando tiene sentido. A veces, una propiedad privada puede ocultar detalles de implementación como la carga diferida, el hecho de que una propiedad es realmente un conglomerado de varios campos y aspectos, o que una propiedad necesita ser instanciada virtualmente con cada llamada (piense
DateTime.Now
). Definitivamente, hay momentos en los que tiene sentido imponer esto incluso a ti mismo en el back-end de la clase.fuente
Los uso en la serialización, con cosas como
DataContractSerializer
o protobuf-net que admiten este uso (XmlSerializer
no). Es útil si necesita simplificar un objeto como parte de la serialización:fuente
Una cosa que hago todo el tiempo es almacenar variables / caché "globales" en
HttpContext.Current
fuente
Los uso de vez en cuando. Pueden facilitar la depuración de cosas cuando puede poner fácilmente un punto de interrupción en la propiedad o puede agregar una declaración de registro, etc.
También puede ser útil si luego necesita cambiar el tipo de datos de alguna manera o si necesita usar la reflexión.
fuente
Utilizo propiedades privadas para reducir el código para acceder a subpropiedades que a menudo utilizo.
Es útil si hay muchas propiedades secundarias.
fuente
Es una práctica común modificar solo miembros con métodos get / set, incluso privados. Ahora, la lógica detrás de esto es para que sepa que su get / set siempre se comporta de una manera particular (por ejemplo, desencadenando eventos) que no parece tener sentido ya que no se incluirán en el esquema de propiedad ... pero los viejos hábitos tardan en morir.
fuente
Tiene mucho sentido cuando hay una lógica asociada con el conjunto de propiedades u obtener (piense en la inicialización diferida) y la propiedad se usa en algunos lugares de la clase.
Si es solo un campo de respaldo recto? Nada me viene a la mente como una buena razón.
fuente
Sé que esta pregunta es muy antigua, pero la información a continuación no figura en ninguna de las respuestas actuales.
Si está inyectando sus dependencias, es posible que desee tener un Getter en una Propiedad y no un setter, ya que esto denotaría una Propiedad de solo lectura. En otras palabras, la propiedad solo se puede establecer en el constructor y no se puede cambiar por ningún otro código dentro de la clase.
Además, Visual Studio Professional proporcionará información sobre una Propiedad y no un campo, lo que facilita ver qué campo se está utilizando.
fuente
Bueno, como nadie mencionó, puede usarlo para validar datos o bloquear variables.
Validación
Cierre
Nota: Al bloquear una referencia, no bloquea el acceso a los miembros del objeto referenciado.
Referencia diferida: cuando la carga diferida puede terminar necesitando hacerlo asíncrono para lo que hoy en día existe AsyncLazy . Si tiene versiones anteriores a las de Visual Studio SDK 2015 o no las usa, también puede usar AsyncLazy de AsyncEx .
fuente
Algunos usos más exóticos de campos explícitos incluyen:
ref
oout
con el valor, tal vez porque es unInterlocked
contadorstruct
diseño explícito (quizás para asignar a un volcado de C ++unsafe
código de )BinaryFormatter
el manejo automático de campo (cambiar a accesorios automáticos cambia los nombres y, por lo tanto, rompe el serializador)fuente