2008-11-11 21 views
10

estoy aburrido y la zona de código con intento de captura como esta ..¿Cómo deshacerse de try catch?

try 
{ 
    //some boring stuff 
} 
catch(Exception ex) 
{ 
    //something even more boring stuff 
} 

me gustaría algo así como

SurroundWithTryCatch(MyMethod) 

Yo sé que puedo lograr este comportamiento mediante la creación de un delegado con la firma exacta de la función, pero crear un delegado para todos los métodos en mi aplicación simplemente no es una opción.

También puedo hacer esto mediante la inyección de código IL, pero esto es caro en términos de rendimiento, ya que crea un ensamblaje de envoltura alrededor del mío.

¿Alguna otra idea válida?

Respuesta

23

En primer lugar, parece que puede estar utilizando try/catch con demasiada frecuencia, especialmente si está capturando Exception. los bloques try/catch deben ser relativamente raros; a menos que realmente pueda "manejar" la excepción, debería dejarla pasar a la siguiente capa de la pila.

Ahora, suponiendo que realmente hace quiere todos estos bloques try/catch, ¿por qué no es una opción crear un delegado? Con métodos anónimos y expresiones lambda, así como los delegados de Func/Action en el espacio de nombres System, básicamente hay muy poco trabajo por hacer. Usted escribe:

public void SurroundWithTryCatch(Action action) 
{ 
    try 
    { 
     action(); 
    } 
    catch(Exception ex) 
    { 
     //something even more boring stuff 
    }  
} 

y luego su SurroundWithTryCatch(MyMethod) va a funcionar bien, si no toma parametros.

Alternativamente, si usted no quiere llamar a un método diferente , acaba de escribir:

public void MyMethod() 
{ 
    SurroundWithTryCatch(() => 
    { 
     // Logic here 
    }); 
} 

Si tiene que volver a partir del método, que puede hacer:

public int MyMethod() 
{ 
    return SurroundWithTryCatch(() => 
    { 
     // Logic here 
     return 5; 
    }); 
} 

con una sobrecarga genérica de SurroundWithTryCatch de esta manera:

public T SurroundWithTryCatch<T>(Func<T> func) 
{  
    try 
    { 
     return func(); 
    } 
    catch(Exception ex) 
    { 
     //something even more boring stuff 
    }  
} 

La mayor parte de esto también estaría bien en C# 2, pero la inferencia de tipo no te ayudará tanto y tendrás que usar métodos anónimos en lugar de expresiones lambda.

Para volver al principio: intente utilizar try/catch con menos frecuencia. (try/finally debería ser mucho más frecuente, aunque generalmente se escribe como una instrucción de uso.)

+0

@Jon ahh me ganaste it..DAM YOU;) –

3

Puede intentar usar alguna validez nula en su lugar. Puedo tomar un ejemplo de LINQ a SQL:

var user = db.Users.SingleOrDefault(u => u.Username == 3); 

if (user == null) 
    throw new ArgumentNullException("User", "User cannot be null."); 

// "else" continue your code... 
+0

En realidad, nunca deberías lanzar 'NullReferenceException'. Esto está reservado para el tiempo de ejecución. Podrías intentar aunque 'ArgumentNullException' –

+0

Lo siento. Lo escribí con prisa. Lo cambiaré de inmediato. Gracias :) – stiduck

2

¿Quizás está tratando el manejo de excepciones como códigos de error a través de una sintaxis diferente? Entonces no intentes/atrape. Deje que la excepción se propague hacia arriba.

0

No estoy seguro de C#, pero en Java-land podría definir e interactuar con todos los métodos, y luego ocultarlo en un objeto proxy. Se podía huir con la escritura de código aún más mediante la definición de algo como:

ExceptionCatcher.catchAll(new Runnable() { 
    public void run() { 
    //run delegate here 
    MyMethod(); 
    } 
}); 

y catchAll() simplemente llamará al ejecutable y envolviendo un bloque try-catch alrededor de ella.

Sin embargo, creo que lo que realmente quieres es un lenguaje que tenga buen aspecto closure support. Usar cierres, hacer lo que quieras es extremadamente fácil.

+0

Afortunadamente, C# * es * un lenguaje con buen soporte de cierre :) (La pregunta no indica el idioma, pero se puede inferir por el código y mencionando IL y delegados). –

2

Para mí, parece que está pidiendo una programación orientada a aspectos. Creo que deberías echarle un vistazo a PostSharp.

+0

gracias, creo que eso es lo que quería, ¿has utilizado este enfoque en un código de producción? –

4

La programación orientada a aspectos también podría ayudarlo, pero esto puede requerir que agregue bibliotecas a su proyecto, postsharp lo ayudaría en este caso. Ver este enlace http://doc.postsharp.org/1.0/index.html#http://doc.postsharp.org/1.0/UserGuide/Laos/AspectKinds/OnExceptionAspect.html#idHelpTOCNode650988000

+0

hey, eso es exactamente lo que yo quería, ¿tienes alguna experiencia con esto? ¿Recomendarías usarlo en lugar del modo clásico? –

+0

Lo he usado solo para aprender propósitos, no en un proyecto real. Personalmente, me gusta mucho este concepto. –