2009-06-25 46 views
5

我有有不同的逻辑不够,但几乎同样的异常处理两个功能:在C#中重用异常处理逻辑的最佳方式是什么?

public void DoIt1 // DoIt2 has different logic but same exception handling 
{ 
    try 
     ... DoIt1 logic 
    catch (MySpecialException myEx) 
    { 
     Debug.WriteLine(myEx.MyErrorString); 
     throw; 
    } 
    catch (Exception e) 
    { 
     Debug.WriteLine(e.ToString()); 
     throw; 
    } 
} 

这是不可能使用一个单一的切入点DoIt1和DoIt2,因为它们从外部要求收回。 复制/ Pase(对于异常块)是最佳方法吗?

回答

6

这取决于...如果有那么多共性,你可以通过在作为一个参数 - 无论是作为一个接口或委托:

void Foo(Action thingToDo) { 
    if(thingToDo == null) throw new ArgumentNullException("thingToDo"); 
    try { 
     thingToDo(); 
    } catch {...} // lots of 
} 

并调用如:

Foo(delegate { /* logic A */ }); 

Foo(delegate { /* logic B */ }); 
5

尝试:

public static class Catching<TException> where TException : Exception 
{ 
    public static bool Try<T>(Func<T> func, out T result) 
    { 
     try 
     { 
      result = func(); 
      return true; 
     } 
     catch (TException x) 
     { 
      // log exception message (with call stacks 
      // and all InnerExceptions) 
     } 

     result = default(T); 
     return false; 
    } 

    public static T Try<T>(Func<T> func, T defaultValue) 
    { 
     T result; 
     if (Try(func, out result)) 
      return result; 

     return defaultValue; 
    } 
} 

实施例:

int queueSize = Catching<MyParsingException> 
    .Try(() => Parse(optionStr, "QueueSize"), 5); 

如果Parse抛出一个MyParsingExceptionqueueSize将默认为5,否则使用从Parse返回值(或任何其它异常通常将传播,这通常是你想要的一个意外的例外)。

这有助于避免分手的代码流,并且还集中了你的日志政策。

您可以为特殊情况编写这种异常包装的专用版本,例如,捕捉一组特定的三个例外,或其他。

0

你可能有这样的事情:

public static class ErrorHandler 
{ 

    public static void HandleMyException(MyException myEx) 
    { 
     Debug.WriteLine(myEx.MyErrorString); 
     throw; 
    } 

    public static void HandleException(Exception myEx) 
    { 
     Debug.WriteLine(e.ToString()); 
     throw; 
    } 

} 

,或者在这种特殊情况下,有这样一个比较通用的功能:

public static class ErrorHandler 
{ 

    public static void WriteAndThrow(string msg) 
    { 
     Debug.WriteLine(msg); 
     throw; 
    } 

} 
+0

重载在运行时不做任何事情,并且每个DoIt都有多个捕获,这正是需要避免的。 – 2009-06-25 22:56:05

2

对于可能的解决方案频谱的最末端,检查出面向方面的编程技术和工具,如PostSharpMicrosoft Policy Injection Block。通过这种方式,您可以定义一个方面的,它可以处理异常,可将编织到代码中需要它的所有位置。

1

如果您只是想记录异常的消息和项目,而无需在catch块中进行特殊处理,则可以创建基于反射的对象记录器,并将Exception作为参数传递。这样做,你没有太多的catch块。

如果您是代码的所有者,您可以将日志记录过程放入MySpecialException的构造函数中,删除catch块并使代码更清晰。

相关问题