private string mWhatever;
private string Whatever
{
get
{
return this.mWhatever;
}
set
{
this.mWhatever = value;
}
}
He visto a algunas personas que hacen propiedades para cada miembro, privado o no ... ¿Tiene sentido? Pude ver que tiene sentido en el 1% de los casos en los momentos en que desea controlar el acceso al miembro dentro de la clase que lo contiene porque si no usa las propiedades para cada miembro, generaría inconsistencias y verificar si el el miembro tiene acceso o no (ya que tiene acceso a ambos en el ámbito de la clase).
Algunas buenas respuestas aquí ya, pero creo que la mayoría de ellas pierden un punto de su pregunta:
Creo que esto rara vez es necesario de antemano, para cada miembro . Empezar con
Cuando más tarde llegue a un punto en el que necesite encapsulación o un punto de interrupción condicional para este miembro específico, aún puede reemplazarlo por una propiedad con el mismo nombre, en la mayoría de los casos sin cambiar el código que utiliza
Whatever
. Pero cuidado, hay diferencias sutiles, vea la respuesta de Brian Rasmussen en esta publicación SO (enlace también proporcionado por Emmad Kareem, +1).fuente
Una de las mayores ventajas de este enfoque es que puede controlar cuándo cambian sus variables .
Considera lo siguiente.
Estás depurando un gran proyecto. Un cierto método arroja una excepción. Establece un punto de interrupción y revela que una determinada variable miembro tiene un valor incorrecto. Digamos que su código se basa en esta variable de manera muy extensa, y encontrará cientos de usos de escritura ( escenario Spaghetti ). Por lo tanto, no puede determinar cuál de estos usos asignó un valor incorrecto.
Si el código es multiproceso, la depuración puede convertirse en una verdadera pesadilla.
Con la propiedad, puede establecer un punto de interrupción en un setter . Combinado con una condición, puede ser clavado en una sola carrera.
VC ++ tiene puntos de corte de datos , pero solo está disponible para código no administrado.
fuente
Si no usa una propiedad, su única otra opción es usar un campo para almacenar datos variables. Las propiedades y los campos tienen diferencias significativas. La mayoría de estas diferencias se encuentran en Campos vs. Propiedades . Le sugiero que estudie las diferencias y luego elija según las necesidades de su aplicación. Sin embargo, tenga en cuenta que el uso de campos en lugar de propiedades no es una práctica común de OO debido a su naturaleza y deficiencias.
fuente
Las propiedades privadas pueden ser muy útiles para encapsular el comportamiento de cosas que son internas de su clase. El hecho de que sean privados no significa que no debas aprovechar el azúcar sintáctico que te dan las propiedades.
Sin embargo, el ejemplo dado es pobre. Los captadores y establecedores de propiedades de este tipo son casi siempre una mala idea. Si está utilizando C # 3.0 o posterior, las propiedades automáticas son una idea mucho mejor:
Esto es más corto, más limpio y mucho más legible. De hecho, es apenas más largo que simplemente declarar la variable de respaldo.
Sin embargo, lo más importante es que las propiedades automáticas se pueden convertir en propiedades completas en cualquier momento sin cambiar la semántica del resto del programa. Por lo tanto, si necesita agregar validación o manejo de errores, puede hacerlo fácilmente.
Tal como están las cosas, siempre pensé que era una lástima que no pudieras tener una propiedad de solo lectura, para exigir solo poder escribir en el valor en el constructor ( prefiero los tipos inmutables ), pero esto se agregó en C # 6.0 como "Inicializadores de propiedad automática", que le permite hacer:
o
junto con
en el constructor
fuente
No es absolutamente necesario hacer esto para propiedades privadas, pero permite modificar cómo la propiedad obtiene / establece el valor subyacente sin cambiar la forma en que se accede.
Por ejemplo, modificando cómo se establece el valor subyacente:
fuente
Si
Yo personalmente uso esto como mecanismo de almacenamiento en caché, y podríamos llamarlo almacenamiento en caché a nivel de propiedad .
Ahora en otros lugares dentro de mi clase, uso la
Users
propiedad en lugar delusers
campo.Otra situación factible podría ser cuando desea implementar algo de lógica en un campo, pero de manera centralizada en una clase. Así, ambos pueden crear un
GetFoo()
método o unaFoo
propiedad para elfoo
campo.fuente
Algo más a considerar:
Las propiedades reales son un detalle de implementación. Uno de los objetivos de OOP es tratar de minimizar la exposición de los detalles de implementación donde sea práctico.
La razón de esto es que si oculta las propiedades y solo las expone a través de getters y setters, tiene mucho más control. Por ejemplo, su captador puede validar su entrada y evitar que la propiedad se establezca en un estado no válido. Si la capacidad de cambiar el valor es de tiempo crítico, entonces el colocador puede proteger contra esto también. El getter, si el valor real es costoso por cualquier razón, puede realizar una inicialización y / o almacenamiento en caché.
Tener getters y setters expuestos y las propiedades ocultas significa que a veces no se necesita ninguna propiedad. Su captador puede calcular el valor en la invocación, o delegar la tarea en otro lugar, o cualquier cosa que le permita cumplir con sus especificaciones. Lo importante de su clase es la información a la que puede acceder desde ella, no cómo esa información se representa internamente.
Por supuesto, si no hay consecuencias negativas para que algo fuera de la clase pueda acceder a una propiedad directamente, entonces debe hacerlo público. Sin embargo, en mi experiencia, estos casos son relativamente pocos y distantes entre sí.
fuente
Sé que esta es una vieja pregunta y todo lo que @Yusubov dijo es correcto, pero con respecto a su segundo punto sobre la lógica específica en el setter, y como no vi a nadie mencionar esto específicamente, un ejemplo perfecto sería cuando su clase implementa la
INotifyPropertyChanged
interfazEsto se utiliza una tonelada en WCF y Silverlight, lo que le permite saber cuándo una propiedad específica ha cambiado a través de la lógica en su setter como en la clase a continuación:
fuente