2010-04-22 5 views
50

¿Es incorrecto tener una declaración de devolución en un bloque catch? ¿Cuáles son las alternativas?
es decir:¿Retorno en bloque de captura?

public bool SomeFunction() 
{ 
    try 
    { 
     //somecode 
     return true; 
    } 
    catch(Exception ex) 
    { 
     MessageBox.Show(ex.message); 
     return false; 
    } 

} 
+0

Vea también: http://stackoverflow.com/questions/2373560/return-statements-in-catch-blocks, http: // stackoverflow.com/questions/449099/is-it-bad-practice-to-return-from-within-a-try-catch-finally-block, http://stackoverflow.com/questions/1713388/in-the- try-catch-block-is-it-bad-to-return-inside-the-catch-which-is-good-practi – outis

+0

está bien, ¿por qué no? – Andrey

Respuesta

31

Puede volver normalmente del bloque catch. Normalmente es un buen código funcional.

0

Tiene perfecto sentido para mí para una función que devuelve verdadero en el éxito y falso en el fracaso. Espero que no hay nada malo en ello - lo hago todo el tiempo :)

18

Una alternativa sería la de almacenar el valor de retorno en una variable temporal:

public bool SomeFunction() 
{ 
    bool success = true; 
    try 
    { 
     //somecode 
    } 
    catch(Exception ex) 
    { 
     MessageBox.Show(ex.message); 
     success = false; 
    } 

    return success; 
} 

Pero personalmente, creo que la forma en que Lo he escrito (con una declaración de catch catch) para que sea más legible. Por otro lado, si usted está esperando una excepción específica y puede que tenga varios caminos para volver éxito o no ...

try 
{ 
    DoTheImportantThing(); 
    DoTheOtherThingThatMightFailButWeDontCare(); 
} 
catch (DontCareAboutItException ex) 
{ 
    log.Info(ex); 
} 
catch (Exception ex) 
{ 
    log.Error(ex); 
    return false; 
} 

return true; 

A continuación, en mi opinión es el mejor de empujar las sentencias de retorno lo más cerca del final como sea posible.

Como nota aparte, dependiendo de la aplicación, considere registrar las excepciones que detecta en lugar de solo mostrarlas al usuario. Las excepciones registradas son mucho más confiables que los recuentos del usuario de lo que sucedió.

7
public bool SomeFunction() 
{ 
    try 
    { 
     //somecode 
     return true; 
    } 
    catch(Exception ex) 
    { 
     MessageBox.Show(ex.message); 
    } 
    return false; 
} 

Personalmente coloco la declaración de devolución en la parte inferior del método en lugar de en el bloque catch. Pero ambos están bien. Se trata de la legibilidad (subjetiva) y las pautas en su organización.

0

El objetivo principal de un bloque catch es proporcionar un lugar donde se pueda proceder a una situación excepcional que se produjo en un bloque try. Entonces captó una excepción, procedió ... y regresó de un método. Si el método de la persona que llama no se preocupa por la excepción, esto es absolutamente normal.

8

Está bien, solo tenga en cuenta que se puede ejecutar algún código después de la instrucción de retorno (el valor de retorno se cobrará).

try 
    { 
     return; 
    } 
    catch(Exception ex) 
    { 
     return; 
    } 
    finally 
    { 
     //some code 
    } 
9

Si en el bloque try ya hay una declaración de retorno que probablemente poner el otro retorno al final de la función:

try 
{ 
    //somecode 
    return true; 
} 
catch(Exception ex) 
{ 
    MessageBox.Show(ex.message); 
} 
return false; 

Y esto con el fin de evitar múltiples retornos si varias excepciones necesitan ser manejado.

+0

Si sigo el patrón de poner return return dentro, entonces el compilador me recordará con error si en caso de alguna forma durante la refactorización borro accidentalmente mi declaración de devolución dentro del try. Pero si mantengo el retorno después de la captura, entonces el código se compilará y podría terminar en prod. – Unnie

2

No es incorrecto, pero si usó un recurso, generalmente finalmente se usa bloquear para cerrarlo, en lugar de llamar al método de cierre dos veces también. En ese caso, puede optar por usar la declaración return después del bloque finally.

+5

'finally' todavía se ejecutará incluso con un retorno en el bloque try. – fearofawhackplanet

+1

En este caso return statement after finally solo causará confusión. Funcionará, pero es una buena práctica no complicar tu código (demasiado). –

2

Sí, es perfectamente normal.

No olvide, que también puede usar finalmente el bloque que se ejecutará después del regreso.

+2

Y, por lo tanto, el código sería difícil de leer dado que el código se está ejecutando después de la devolución. –

+2

No lo entiendo, ¿consideras finalmente que bloquear es difícil de leer? –

+1

Poner un retorno en un bloque catch puede ser difícil de leer porque esperas que el retorno pase por alto la instrucción finally. Lo mismo podría decirse de poner un bloque de retorno en el bloque try. Por lo general, el retorno significa "todas las ejecuciones en el método se detienen y el control vuelve a la persona que llama", mientras que el bloque final siempre se ejecuta al salir del try/catch, por lo que no es fácil predecir cuál tendrá prioridad. – Trisped

2

En general, no hagas eso. El problema es que, visual y técnicamente, la lógica de la captura requiere salir del bloque catch. Por ejemplo, si tienes un bloque final, ¿qué crees que te dará este código?

int Test(out int t) 
    { 
     int i = 1; 
     t = 1; 
     try 
     { 
      if(DateTime.Now.Second < 58) 
       throw new Exception(); 
     } 
     catch (Exception) 
     { 
      return i; 
     } 
     finally 
     { 
      i = 2; 
      t = 2; 
     } 

     return -1; 
    } 

Respuesta: volvería 1 como si hubiéramos ejecutado solamente i = 1 pero tendría t = 2 a pesar de que t = 2 sucedió después de i = 2.

Como se puede ver lo visual y la regla técnica de "no se ejecutará código después de la devolución" está rota.

0

Puede agregar return en el bloque catch. Usted sabe explícitamente que su código regresará y continuará la ejecución en lugar de detenerse en el bloque catch.

try{ 
    //do something 
} 
catch{ 
    //error handling 
    return; 
} 

En lugar de tener una gran cantidad de bloques try-catch en su código que puede ser confuso y simplemente causar un desastre en su código, que es mejor manejar todo en su captura NOE oportunidad y simplemente comprobar lo que devuelve el error era .

try{ 
    //do something 
} 
catch (Exception as err){ 
    if (err == "IOException"){ 
     //handle exception 
    else if (err.indexOf("TypeError"){ 
     //handle exception 
    } 
} 

Estas son dos formas de verificar qué tipo era la excepción para que pueda mostrar un mensaje en consecuencia. También puede capturar excepciones específicas si así lo desea en lugar de Exception as err puede hacer catch IOException, ...

Cuestiones relacionadas