visual studio setters property getters example and properties setter getter

properties - studio - Lo que deben y no deben hacer los captadores y los instaladores



python property example (3)

Posible duplicado:
Pregunta de la convención: ¿Cuándo se usa una función Getter / Setter en lugar de una propiedad?

Últimamente me he topado con muchas opiniones diferentes sobre Getters y Setters, así que pensé que debería convertirlo en su propia pregunta.

Una de mis preguntas anteriores recibió un comentario inmediato (luego se eliminó) de que los establecedores establecidos no deberían tener ningún efecto secundario, y un método SetProperty sería una mejor opción.

De hecho, esta parece ser también la opinión de Microsoft . Sin embargo, sus propiedades a menudo provocan eventos, como el Resized cuando se establece la propiedad Width o Height un formulario. OwenP también afirma que "no debe permitir que una propiedad arroje excepciones, las propiedades no deberían tener efectos secundarios, el orden no debería importar y las propiedades deberían regresar con relativa rapidez".

Sin embargo, Michael Stum afirma que se deben lanzar excepciones al validar los datos dentro de un configurador. Si su configurador no lanza una excepción, ¿cómo podría validar los datos de manera efectiva, como sugieren muchas de las respuestas a esta pregunta ?

¿Qué pasa cuando necesitas organizar un evento, como lo hacen casi todos los controles de Microsoft? ¿No estás entonces a merced de quien se suscriba a tu evento? Si su manejador realiza una gran cantidad de información, o lanza un error en sí mismo, ¿qué sucede con su configurador?

Por último, ¿qué pasa con la carga perezosa dentro del getter? Esto también podría violar las directrices anteriores.

¿Qué es aceptable colocar en un getter o setter, y qué se debe mantener solo en los métodos de acceso?

Editar:

De otro article en el MSDN:

Los métodos get y set generalmente no son diferentes de otros métodos. Pueden ejecutar cualquier lógica de programa, lanzar excepciones, anularse y declararse con cualquier modificador permitido por el lenguaje de programación. Tenga en cuenta, sin embargo, que las propiedades también pueden ser estáticas. Si una propiedad es estática, existen limitaciones sobre lo get pueden hacer los métodos get y set . Vea la referencia de su lenguaje de programación para más detalles.


Estoy de acuerdo con la idea de que los captadores / configuraciones no deberían tener efectos secundarios, pero diría que no deberían tener efectos secundarios no obvios.

En cuanto a las excepciones de lanzamiento, si está configurando una propiedad en un valor no válido (en un sentido muy básico), las excepciones de validación están bien. Sin embargo, si el configurador está ejecutando series completas de validación de reglas de negocios complicadas, o está intentando apagar y actualizar otros objetos, o cualquier otra cosa que pueda causar una excepción, entonces eso es malo. Pero este problema no es realmente un problema con la excepción en sí, sino que el configurador se está apagando y está ejecutando secretamente una gran cantidad de funcionalidades que la persona que llama no espera (o no debería) esperar.

Lo mismo con los eventos. Si un colocador está lanzando un evento que dice que "esta propiedad cambió", entonces está bien, porque es un efecto secundario obvio. Pero si se está activando algún otro evento personalizado, por lo tanto, la ejecución de algún código oculto en otra parte de un sistema es malo.

Esta es la misma razón por la que evito la carga perezosa en getters. De hecho, pueden hacer las cosas más fáciles la mayor parte del tiempo, pero pueden hacer que las cosas se vuelvan más confusas en algunas ocasiones, porque siempre termina siendo una lógica intrincada en torno a cuándo se cargan los objetos secundarios. Por lo general, solo es una línea más de código para cargar explícitamente los objetos secundarios cuando se está rellenando el objeto principal, y puede evitar una gran confusión sobre el estado del objeto. Pero este aspecto puede ser muy subjetivo, y mucho depende de la situación.


Mi vista:

  1. Si se espera que un setter o getter sea costoso, no lo conviertas en una propiedad, hazlo en un método.

  2. Si establecer una propiedad activa eventos debido a cambios, esto está bien. ¿De qué otra manera permitiría que los oyentes sean notificados de los cambios? Sin embargo, es posible que desee ofrecer un par BeginInit / EndInit para suprimir eventos hasta que se realicen todos los cambios. Normalmente, es responsabilidad del controlador del evento regresar rápidamente, pero si realmente no puede confiar en que lo haga, entonces es posible que desee señalar el evento en otro hilo.

  3. Si establecer una propiedad genera excepciones en valores no válidos, también está bien. Esta es una forma razonable de señalar el problema cuando el valor es completamente incorrecto. En otros casos, establece un grupo de propiedades y luego llama a un método que las usa para hacer algo, como hacer una conexión. Esto permitiría retener la validación y el manejo de errores hasta que se usen las propiedades, por lo que las propiedades no necesitarían lanzar nada.

  4. El acceso a una propiedad puede tener efectos secundarios siempre que no sean inesperados y no importen. Esto significa que una instanciación JIT en un captador está bien. Del mismo modo, establecer una bandera sucia para la instancia cada vez que se realiza un cambio está bien, ya que establece una propiedad relacionada, como un formato diferente para el mismo valor.

  5. Si hace algo en lugar de solo acceder a un valor, debería ser un método. Los métodos son verbos, por lo que la creación de una conexión se haría mediante el método OpenConnection (), no una propiedad de Conexión. Se usaría una propiedad de conexión para recuperar la conexión en uso, o para vincular la instancia a otra conexión.

editar - añadido 5, cambiado 2 y 3


Siempre he encontrado que el enfoque conservador es el mejor, al trabajar en C # de todos modos. Debido a que las propiedades son sintácticamente iguales a los campos, deberían funcionar como campos: sin excepciones, sin validación, sin negocios graciosos. (De hecho, la mayoría de mis propiedades comienzan como campos simples y no se convierten en propiedades hasta que son absolutamente necesarias). La idea es que si ves algo que parece que está recibiendo o configurando un conjunto de campos, entonces es algo como obtener o estableciendo un campo, en términos de funcionalidad (no se lanzan excepciones), eficiencia general (las variables de configuración no activan una cascada de llamadas delegadas, por ejemplo) y afectan el estado del programa (la configuración de una variable establece esa variable, y no lo hace) Llamo a muchos delegados que podrían hacer casi cualquier cosa).

Las cosas sensatas que debe hacer una propiedad incluyen el establecimiento de una bandera para indicar que ha habido un cambio:

set { if(this.value!=value) { this.changed=true; this.value=value; } }

Quizás en realidad establezca un valor en otro objeto, por ejemplo:

set { this.otherObject.value=value; }

Tal vez desenrede la entrada un poco, para simplificar el código interno de la clase:

set { this.isValid=(value&Flags.IsValid)!=0; this.setting=value&Flags.SettingMask; }

(Por supuesto, en estos dos últimos casos, la función get podría hacer lo contrario).

Si es necesario que suceda algo más complicado, en particular, llamar a los delegados, realizar una validación o lanzar excepciones, mi opinión es que una función es mejor. (Muy a menudo, mis campos se convierten en propiedades con obtener y establecer, y luego terminan como una propiedad de obtención y una función de configuración). De manera similar para los captadores; Si está devolviendo una referencia a algo, no hay problema, pero si está creando un objeto grande completamente nuevo y rellenándolo cada vez que se lee la propiedad, no tanto.