Siempre he pensado que las propiedades (es decir, sus operaciones set / get) deberían ser rápidas / inmediatas y sin fallas. Nunca debería tener que tratar de atrapar y obtener o establecer una propiedad.
Pero estoy buscando algunas formas de aplicar seguridad basada en roles en las propiedades de algunos objetos. Por ejemplo, una propiedad Employee.Salary. Algunas de las soluciones que he encontrado que otras han probado (una en particular es el ejemplo de AOP aquí ) implican lanzar una excepción si el descriptor de acceso no tiene los permisos correctos, pero esto va en contra de una regla personal que he tenido por mucho tiempo ahora.
Entonces pregunto: ¿estoy equivocado? ¿Han cambiado las cosas? ¿Se ha aceptado que las propiedades deberían poder lanzar excepciones?
fuente
Respuestas:
cuando establece el valor de una propiedad, lanzar una excepción en un valor no válido está bien
obtener el valor de una propiedad (casi) nunca debería arrojar una excepción
para el acceso basado en roles, use interfaces o fachadas diferentes / más tontas; ¡no dejes que la gente vea cosas que no puede tener!
fuente
Considero que en su mayoría es una mala forma, pero incluso Microsoft recomienda usar excepciones a veces. Un buen ejemplo es la propiedad abstracta Stream.Length . A medida que avanzan las pautas, me preocuparía más evitar los efectos secundarios en los captadores y limitar los efectos secundarios en los setters.
fuente
Definitivamente, argumentaría que hay un defecto en el diseño si siente la necesidad de lanzar excepciones de un establecedor de propiedades o getter.
Una propiedad es una abstracción que representa algo que es solo un valor . Y debe poder establecer un valor sin temor a que hacerlo pueda generar una excepción. *
Si establecer la propiedad resulta en un efecto secundario, eso debería implementarse realmente como un método. Y si no produce ningún efecto secundario, no se debe lanzar ninguna excepción.
Un ejemplo ya mencionado en una respuesta diferente es la
Stream.Position
propiedad. Esto produce efectos secundarios y puede generar excepciones. Pero este configurador de propiedades es básicamente un envoltorioStream.Seek
que podría llamar en su lugar.Personalmente, creo que el puesto no debería haber sido una propiedad escribible.
Otro ejemplo en el que podría verse tentado a lanzar una excepción desde un configurador de propiedades es en la validación de datos:
Pero hay una mejor solución a este problema. Introduzca un tipo que represente una dirección de correo electrónico válida:
los
Email
clase garantiza que no puede contener un valor que no sea una dirección de correo electrónico válida, y las clases que necesitan almacenar correos electrónicos quedan libres del deber de validarlas.Esto también conduce a una mayor cohesión (un indicador de un buen diseño de software): el conocimiento sobre qué es una dirección de correo electrónico y cómo se valida solo existe en el
Email
clase, que solo tiene esa preocupación.* ObjectDisposedException es la única excepción válida (sin juego de palabras) que se me ocurre en este momento.
fuente
Sé que su pregunta es específica de .NET , pero dado que C # comparte algo de historia con Java, pensé que podría estar interesado. Soy no de ninguna manera implica que, debido a que se haga algo en Java, se debe hacer en C #. Sé que los dos son muy diferentes, especialmente en cómo C # tiene un soporte de nivel de lenguaje muy mejorado para las propiedades. Solo estoy dando un poco de contexto y perspectiva.
De la especificación JavaBeans :
Toma todo esto con un grano de sal, por favor. La especificación JavaBeans es antigua, y las propiedades de C # son (IMO) una gran mejora con respecto a las propiedades basadas en "convención de nomenclatura" que tiene Java. Solo estoy tratando de dar un poco de contexto, ¡eso es todo!
fuente
El punto de una propiedad es el Principio de acceso uniforme , es decir, que un valor debe ser accesible a través de la misma interfaz, ya sea implementado por almacenamiento o cálculo. Si su propiedad está lanzando una excepción que representa una condición de error más allá del control del programador, del tipo que se supone que debe ser capturado y manejado, está obligando a su cliente a saber que el valor se obtiene a través del cálculo.
Por otro lado, no veo ningún problema con el uso de afirmaciones o excepciones de aserción que pretenden indicar el uso incorrecto de la API al programador en lugar de ser detectado y manejado. En estos casos, la respuesta correcta desde la perspectiva del usuario de la API no es manejar la excepción (por lo tanto, preocuparse implícitamente sobre si el valor se obtiene a través del cálculo o el almacenamiento). Es para arreglar su código para que el objeto no termine en un estado no válido o hacer que corrija su código para que la afirmación no se active.
fuente
AFAIK, esta guía proviene principalmente del proceso de pensamiento de que las propiedades pueden terminar siendo utilizadas en el momento del diseño . (Por ejemplo, la propiedad Text en un TextBox) Si la propiedad arroja una excepción cuando un diseñador intenta acceder a ella, VS no tendrá un buen día. Obtendrá un montón de errores al intentar usar el diseñador y para los diseñadores de la interfaz de usuario, no se procesarán. También se aplica al tiempo de depuración, aunque lo que verá en un escenario de excepción es solo "xxx Exception" y no afectará VS IIRC.
Para los POCO, en realidad no hará ningún daño, pero aún así evito hacerlo yo mismo. Me imagino que las personas querrán acceder a las propiedades con mayor frecuencia, por lo que normalmente deberían ser de bajo costo. Las propiedades no deberían hacer el trabajo de los métodos, solo deberían obtener / configurar cierta información y hacerlo como una regla general.
fuente
Aunque mucho dependerá del contexto, generalmente evitaría poner cualquier tipo de lógica rompible (incluidas las excepciones) en las propiedades. Solo como un ejemplo, hay muchas cosas que usted (o alguna biblioteca que está usando) podría hacer que usan la reflexión para iterar sobre las propiedades que resultan en errores que no anticipó en tiempo de diseño.
Sin embargo, digo en general, ya que puede haber ocasiones en las que, definitivamente, quieras bloquear algo sin preocuparte demasiado por las consecuencias. Seguridad, supongo, sería el caso clásico allí.
fuente