2009-06-25 72 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塊並使代碼更清晰。

相關問題