Para una típica if...else
envoltura con manejo de excepciones, ¿es algo como el siguiente ejemplo una práctica recomendada para evitar la duplicación de código?
try
{
if (GetDataFromServer())
{
return ProcessData();
}
else
{
throw new Exception();
}
catch(Exception ex)
{
return null;
}
en vez de...
try
{
if (GetDataFromServer())
{
return ProcessData();
}
else
{
return null;
}
}
catch(Exception ex)
{
return null;
}
Sé que hay un pequeño éxito en el rendimiento, pero me pregunto si esto se considera una práctica aceptable. Actualmente lo hago con el segundo método, especialmente en los casos en que necesito manejar excepciones específicas de manera diferente, pero me preguntaba si el primer método es apropiado para casos simples.
c#
exception-handling
grovesNL
fuente
fuente
Respuestas:
Microsoft desaconseja el uso de manejo de excepciones para el control de flujo.
Y una mesa redonda sobre el tema está disponible.
Dicho esto, C # admite hacerlo, y supongo que depende de la condición encontrada si una excepción es la respuesta más adecuada.
fuente
El impacto en el rendimiento es probablemente insignificante, como se explica en esta respuesta .
Así que vamos con la idea de que el rendimiento no es un problema. Estás lanzando
System.Exception
, solo para mover la ejecución a lacatch
cláusula .BadControlFlowThatShouldBeRewrittenException
Sin embargo, arrojar un probablemente sería exagerado.Analicemos esto. Tenemos:
GetDataFromServer
(los nombres de los métodos deben ser PascalCase en C #), que posiblemente puede generar una excepción o devolver abool
.true
, correProcessData
.null
otra manera.Parece que el método donde se escribe este código es simplemente hacer demasiadas cosas.
GetDataFromServer
devolver unbool
aspecto parece un defecto de diseño, esperaría que ese método devuelva los datos que está obteniendo del servidor , algunosIEnumerable<SomeType>
que contendrían 0 o más elementos, es decir, la ruta feliz devuelve n elementos donde n> 0 , no tan feliz ruta devuelve 0 elementos, y la ruta infeliz explota con una excepción no controlada, sea lo que sea.Eso cambia bastante el aspecto del método; de nuevo, es difícil saber si esto tiene sentido, porque la publicación original solo tiene un punto de salida (y, por lo tanto, no se compilaría, ya que no todas las rutas de código devuelven un valor ), por lo que esto es solo una suposición descabellada:
Aquí mirarías
ProcessData
y verías que está iterandoresult
y devuelvenull
si no hay ningún elemento en elIEnumerable
.Ahora, ¿por qué regresa el método
null
? El servidor estaba caído? ¿Hay algún error en la consulta? ¿La cadena de conexión está usando las credenciales incorrectas? Cada vez queGetDataFromServer
explota con una excepción que no espera, lo está tragando, metiéndolo debajo de la alfombra y devolviendo unnull
valor. Recomiendo capturar excepciones específicas en este caso, y registrar todo lo demás; la depuración será mucho más fácil de esa manera.Con una
catch
cláusula general que no captura la excepción, se hace bastante difícil diagnosticar algo. Mínimamente haría esto en su lugar:Ahora al menos puede romper e inspeccionar
e
si las cosas salen mal.TL; DR : No, lanzar y capturar excepciones para el control de flujo no es una buena idea.
fuente
en su primera respuesta hay un éxito en el rendimiento que no necesita estar allí.
cuando sale de la instrucción if para ingresar a la instrucción Catch cuando no tiene que hacer que el código cambie de dirección, por así decirlo.
si desea
return null;
hacerlo en la instrucción else no en una captura que se captura después de ser arrojada desde la instrucción else.Probablemente no se aplica a su código Real , pero para el código genérico que le dio sí se aplica.
Los estándares dicen que no debes hacer esto.
Los estándares dicen que debe hacerlo así (nuevamente basado en el Código Genérico dado en OP)
y dado que no tiene ninguna excepción específica que esté atrapando, ni siquiera debería intentar probar aquí.
desea ver Excepciones cuando ocurren para que pueda solucionar el problema que crea la excepción.
fuente
¿Por qué no lo más simple?
Si va a existir un controlador de excepción, debería estar en ProcessData ()
fuente
ProcessData()
al nivel más alto?ProcessData()
arroja una excepción ahora no se maneja. Quiero que sea areturn null
este nivel siProcessData()
arroja una excepción, sin modificarseProcessData()
.