c# - ultrasensible - proteina c reactiva valores normales mg/dl
Programación Preventiva vs Reactiva C# (9)
C / C ++ puede ser tan reactivo. ¿Cuántas veces vio algo intentado como un fopen seguido por un cheque NULL? La ventaja de las excepciones es que permiten que se proporcione más información que un retorno NULO o Falso.
La mayoría de las operaciones que arrojan excepciones en cualquier idioma que las respalde no hay forma de "Probar" de antemano para asegurarse de que la operación tenga éxito.
Ahora las excepciones de tiempo de ejecución son algo completamente diferente. Estos son normalmente causados por datos no válidos o un mal uso de los datos (división por cero). Este tipo de excepciones, en mi opinión, nunca deben ser tomadas como una forma de tratar con ellas.
Siempre he sido de los que me he equivocado al prevenir las condiciones de excepción al no tomar una acción a menos que esté seguro de que no habrá errores. Aprendí a programar en C y esta era la única forma de realmente hacer las cosas.
Trabajando con C # Veo con frecuencia una programación más reactiva: intente hacer algo y manejar excepciones. Para mí esto parece usar excepciones como declaraciones de control. Las primeras veces que vi esto lo descarté como una mala práctica. Pero en los últimos meses lo he visto por todos lados y solo tengo que preguntarme: ¿esto es aceptado / eficiente o simplemente es una epidemia?
Actualización: para aclarar un poco, la mayor parte del manejo de excepciones que estoy viendo son cosas como
try
{
//open file
}
catch
{
//message box for file not found
}
o peor
try
{
//open xml
//modify xml (100+ lines of code)
}
catch
{
//message for ''unspecified error''
}
Entiendo que hay momentos en los que el manejo de excepciones es muy bueno (como las conexiones de bases de datos), pero me refiero al uso de excepciones en lugar de un control más ''tradicional''. Le pregunté esto porque sentía que este estilo de programación usaba las excepciones como una muleta en lugar de como un método de recuperación y quería saber si esto era algo que debería aprender a esperar en el mundo de C #.
Ciertamente puede hacer un mal uso de las excepciones es c #. En mi opinión, nunca deberías obtener una ArgumentNullException, ya que siempre deberías probar primero null. Sin embargo, también hay muchos casos en los que no se puede controlar la salida de una excepción. Cualquier cosa que interactúe con "el mundo exterior" (conectarse a un servidor web, base de datos, etc.) puede arrojar una excepción.
Evita tanto como sea posible, pero aún necesitas la capacidad de reaccionar ante todo lo demás.
Como de costumbre, la respuesta es "depende", pero me suscribo a la filosofía "fail fast" en general.
Prefiero usar try / finally (sin captura) a menos que realmente pueda hacer algo útil para recuperar una excepción en un bloque de código en particular. Atrapar todas las posibles excepciones no vale la pena. En general, el fracaso rápido es preferible a fallar silenciosamente.
Si, por otro lado, usted sabe cómo recuperarse de una excepción en particular, entonces sí, haga eso.
Supongamos que tiene una biblioteca de transferencia de archivos. Probablemente lanzará una excepción si la transferencia se interrumpe debido a un tiempo de espera o falla de la red. Es razonable. Te molestarán si la biblioteca falla silenciosamente; buscar un código de retorno es mucho más propenso a errores, y no necesariamente más legible. Pero tal vez tenga una regla de negocio para enviar un montón de archivos a un servidor que debe hacer al menos 3 intentos para transferir el archivo antes de darse por vencido y solicitar la intervención del usuario. En ese caso, la lógica comercial debe manejar la excepción, intentar recuperarla y luego hacer lo que se supone que debe hacer cuando falla la solución automática (alertar al usuario, programar un intento posterior, o lo que sea).
Si encuentras código que hace esto:
try
{
// do something that could throw
// ...
}
catch {} //swallow the exception
o:
catch { return null; }
Eso probablemente esté roto. Claro, a veces el código que llamas puede arrojar una excepción que realmente no te importa. Pero a menudo veo que la gente hace esto solo para no tener que "manejar" la excepción aguas arriba; la práctica hace las cosas más difíciles de depurar.
Algunas personas consideran que permitir excepciones para encauzar la cadena de responsabilidad es malo porque solo "esperas" que alguien corriente arriba "milagrosamente" sepa qué hacer. Esas personas están equivocadas. El código de flujo ascendente es a menudo el único lugar que puede saber qué hacer.
Ocasionalmente, intentaré capturar y arrojar una excepción diferente y más apropiada. Sin embargo, cuando sea posible, una cláusula de guardia es mejor. p.ej. if (argument==null) throw new ArgumentNullException();
es mejor que permitir que una NullReferenceException se propague por la pila de llamadas, porque es más claro lo que salió mal.
Algunas condiciones "nunca deberían suceder" o "no sabía que podría suceder" probablemente deberían registrarse (ver, por ejemplo, registro de jboss), pero se pueden tragar antes de que bajen su aplicación, al menos en algunos casos.
ETA: probablemente esté roto para tomar una excepción específica y luego mostrar un mensaje de error general y ambiguo. Para su segundo ejemplo anterior, eso me suena mal. Para el primero, "Archivo no encontrado", eso puede ser más razonable (si captas esa excepción específica, y no solo "todo"), a menos que tengas una mejor manera de manejar esa condición en otro lugar. Los Messageboxes modales suelen ser un mal "olor de diseño de interacción" para mí, pero eso es casi imposible.
En mis días de C ++ COM, aprendí a no hacer todo lo posible por manejar errores "posibles", es decir, no verifico rutinariamente el valor de retorno de cada llamada de función. Eso es porque sé que no puedo tener éxito en el manejo de condiciones desconocidas:
No sé cuándo va a fallar, o qué significa eso.
No puedo hacerlo posible, así que no puedo probar mi código de manejo de errores. El código que no se prueba es un código que no funciona.
No sé lo que el usuario querría que hiciera.
El manejo rutinario de errores puede permitir que el programa continúe ejecutándose, pero no de una manera confiable y predecible de la que el usuario se beneficie.
Fallar rápida y dramáticamente (en lugar de lenta y sutilmente) no adormece al usuario con una falsa sensación de seguridad y le da al programador una mejor oportunidad de diagnosticar el problema.
Obviamente, no estoy diciendo "nunca maneje errores", estoy diciendo "solo manejar errores cuando se puede agregar valor".
Los mismos principios se aplican a C #. Creo que es una buena idea atrapar una excepción si puedes envolverla en una excepción más relevante y arrojarla en su lugar. Y si está seguro de cómo se beneficiaría su usuario al manejar una excepción, entonces hágalo. Pero de lo contrario, déjalo en paz.
Entrar en un try-block en C ++ es una operación costosa (en términos de ciclos de CPU) por lo que debe minimizar su uso por ese motivo. Para C #, ingresar al try-block es barato, así que podemos usarlo de otra manera.
Ahora; capturar excepciones en C # es costoso, y aún así debería usarse para casos excepcionales y no para la lógica general del programa, como otros ya han indicado aquí ...
Es difícil analizar el mejor uso de las excepciones sin una discusión general de la estrategia de excepción. Por ejemplo, tu estrategia podría ser cualquiera de las siguientes:
- manejar todas las excepciones tan cerca del punto de falla como sea posible
- registrar una excepción, luego volver a lanzar a la persona que llama
- retroceder a un estado previo a la excepción e intentar continuar
- traducir la excepción a un mensaje de error apropiado y mostrarla al usuario
El manejo de excepciones a menudo puede complicarse por el hecho de que varios desarrolladores que trabajan en el mismo proyecto pueden no tener la misma estrategia o, lo que es peor, ni siquiera saber que existe. Entonces, es importante que todos en un equipo conozcan y entiendan cuál es la estrategia.
Para obtener un buen punto de partida sobre el manejo y la estrategia de excepciones, consulte la publicación de blog de Ned Batchelder Exceptions in the Rainforest .
Hay algunos casos en los que se ve obligado a reaccionar: verificar y operar no siempre funciona.
Acceder a un archivo en un disco: ¿está funcionando el disco? ¿existe el archivo? ¿Puedo obtener acceso de lectura al archivo?
Accediendo a una base de datos: ¿el servidor acepta conexiones? ¿Son mis credenciales buenas? ¿Existen los objetos de la base de datos? ¿Las columnas se nombran / escriben apropiadamente?
Todas estas cosas pueden cambiar entre el cheque y la operación.
La clave está en el término "Excepción".
Si el argumento es nulo es una condición comercial válida , entonces, por definición, un argumento nulo no es una excepción, y debe probarse antes de usarlo. El uso de excepciones para controlar la lógica del programa en tales condiciones comerciales es una codificación descuidada, y el perpetrador debe ser abofeteado repetidamente con un eglefino mojado hasta que se arrepienta.
Sin embargo, el rendimiento a un lado, siempre a ciegas pruebas para, en este ejemplo, argumentos nulos, no es mejor que atrapar siempre una excepción cuando se lanza.
Si resulta imposible que un argumento sea nulo , no se debe realizar la prueba de nulo, excepto en la capa superior de la aplicación donde las excepciones no controladas se atrapan, se almacenan, se envían por correo electrónico al equipo de soporte y se ocultan al usuario a quien un mensaje adecuado se debe mostrar a modo de disculpa.
Una vez tuve que depurar una aplicación donde se habían manejado todas las malditas excepciones imaginables, y era literalmente imposible de depurar. Tuvo que ser retirado de la producción, en un envp dev, junto con su base de datos, y todos los manipuladores arrancaron. Después de eso fue trivial.
Creo que tienes razón en que usar excepciones como declaraciones de control es una mala práctica. Las excepciones en .Net son lentas. Siempre es mejor hacer sus propios controles en lugar de usar excepciones para capturar valores "malos", como Nulos, como mencionó Jon B.
Descubrí de primera mano en una aplicación .Net 1.1 que creó archivos de texto delimitados de datos de laboratorio. Estaba usando excepciones para capturar campos que tenían datos no válidos, pero una vez que reemplacé las excepciones con el código de verificación apropiado, la aplicación se aceleró exponencialmente.