¿Deberían las propiedades en C # tener efectos secundarios además de notificar un cambio en sus estados?
He visto propiedades usadas de varias maneras diferentes. Desde las propiedades que cargarán el valor la primera vez que acceden a las propiedades que tienen efectos secundarios masivos como causar una redirección a una página diferente.
Respuestas:
Supongo que está hablando de propiedades de solo lectura , o al menos de captadores de propiedades , ya que un establecedor de propiedades tendrá , en casi todos los casos, efectos secundarios. De lo contrario, no es muy útil.
En general, un buen diseño sigue el principio de la menor sorpresa . No haga cosas que las personas que llaman no esperan que haga, especialmente si esas cosas pueden cambiar los resultados futuros .
En general , eso significa que los captadores de propiedades no deberían tener efectos secundarios.
Sin embargo , tengamos cuidado con lo que entendemos por "efecto secundario".
Un efecto secundario es, técnicamente, cualquier modificación de estado. Ese podría ser un estado de acceso público, o ... podría ser un estado totalmente privado.
Los cargadores perezosos / diferidos son un ejemplo de estado que es casi exclusivamente privado. Mientras no sea responsabilidad de quien llama liberar ese recurso, en realidad está reduciendo la sorpresa y la complejidad en general mediante el uso de inicialización diferida. Una persona que llama normalmente no espera tener que indicar explícitamente la inicialización de una estructura interna . Entonces, la inicialización perezosa no viola el principio anterior.
Otro ejemplo es una propiedad sincronizada. Para que un método sea seguro para subprocesos, a menudo tendrá que estar protegido por una sección crítica o mutex. Entrar en una sección crítica o adquirir un mutex es un efecto secundario; estás modificando el estado, generalmente el estado global . Sin embargo, este efecto secundario es necesario para evitar un tipo de sorpresa mucho peor : la sorpresa de que los datos sean modificados (o peor, parcialmente modificados) por otro hilo.
Así que aflojaría un poco la restricción a lo siguiente: las lecturas de propiedades no deberían tener efectos secundarios visibles o efectos secundarios que cambien su semántica .
Si no hay una forma posible de que una persona que llama se vea afectada por un efecto secundario , o que incluso lo note , ese efecto secundario no está causando ningún daño. Si fuera imposible para usted escribir una prueba para verificar la existencia de un efecto secundario en particular, entonces está lo suficientemente localizado como para etiquetarlo como un detalle de implementación privada y, por lo tanto, no es una preocupación legítima para el mundo exterior.
Pero ten cuidado; Como regla general, debe tratar de evitar los efectos secundarios, porque a menudo lo que usted cree que es un detalle de implementación privada puede filtrarse inesperadamente y hacerse público.
fuente
Contestaré su pregunta con una pregunta: ¿Qué sucede cuando modifica la propiedad Ancho de un formulario?
Justo en la parte superior de mi cabeza, esto:
(Descargo de responsabilidad: soy un desarrollador de Delphi, no un desarrollador de .NET. Esto puede no ser 100% exacto para C #, pero apuesto a que está bastante cerca, especialmente teniendo en cuenta qué parte del marco .NET original se basó en Delphi).
Todos estos "efectos secundarios" ocurren cuando cambia la propiedad Ancho en un formulario. ¿Alguno de ellos parece inapropiado o incorrecto de alguna manera?
fuente
Eche un vistazo a las Reglas de diseño de Microsoft , especialmente una de ellas:
CA1024: use las propiedades donde corresponda
fuente
Creo que las propiedades no deberían tener efectos secundarios. Sin embargo, hay una excepción a esta regla: carga diferida. Si desea cargar algo de forma diferida en una propiedad, está bien, porque el cliente no puede decir que la carga diferida se está ejecutando, y generalmente no le importa.
EDITAR : Oh, una cosa más: disparar un evento que dice "¡PropertyXYZ ha cambiado!" (por ejemplo
INotifyPropertyChanged
) - está bien en los setters.fuente
Además de la carga diferida mencionada anteriormente, también existe el caso de las funciones de registro. Estos serían raros pero no descartados.
fuente
Casi no hay absolutos en la programación, para responder a su pregunta necesitamos analizar algunas propiedades deseables de los objetos y ver si eso es algo que se aplica a nuestro caso
Si respondemos que sí a algunas de estas preguntas, entonces probablemente sea una buena idea pensar con mucho cuidado sobre las propiedades y sus efectos secundarios. Supongo que cuando dice efectos secundarios, se refiere a efectos secundarios secundarios, ya que actualizar el valor es un efecto secundario en sí mismo.
Cuantos más efectos secundarios en general, más difícil será evaluar una clase. Cuantos más efectos secundarios secundarios, más difícil será manejar la concurrencia, pero ese es un problema difícil que probablemente requiere un pensamiento de diseño importante de todos modos.
El gran problema es probablemente para las personas que tratan a su clase como una "caja negra", no estaría fácilmente disponible que algún estado ha cambiado solo porque han leído una propiedad o que alguna otra propiedad cambia porque otra cambia (lo que podría conducir a a actualizaciones en cascada).
Entonces, en general no, queremos que las propiedades sean tan fáciles de razonar y simples como sea posible, eso está un poco implícito en la decisión de diseño; de lo contrario, sería un método. Sin embargo, un buen programador siempre puede romper las reglas, solo asegúrese de tener una muy buena razón :)
fuente