2008-11-11 87 views
10

我厭倦了周圍的代碼與嘗試捕捉這樣的..如何擺脫try catch?

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

我想是這樣

SurroundWithTryCatch(MyMethod) 

我知道我可以用確切的簽名創建委託完成這一行爲的函數,但爲我的應用程序中的所有方法創建一個委託,它只是不是一個選項。

我也可以通過注入IL代碼來做到這一點,但這在性能方面很昂貴,因爲它在我的周圍創建了一個包裝程序集。

任何其他有效的ideeas?

回答

23

首先,它聽起來像你可能經常使用try/catch - 特別是如果你正在捕捉Exception。 try/catch塊應該比較少見;除非你真的可以「處理」這個異常,否則你應該讓它冒泡到堆棧的下一層。

現在,假設你真的想要所有這些try/catch塊,爲什麼它不是一個創建委託的選項?通過匿名方法和lambda表達式,以及System命名空間中的Func/Action委託,基本上沒有什麼工作要做。你寫:

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

,然後你就會SurroundWithTryCatch(MyMethod)正常工作,如果它沒有PARAMATERS。

或者,如果你不想調用不同方法做,只是寫:

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

如果你需要從方法返回,你可以這樣做:

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

SurroundWithTryCatch的通用過載如下:

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

大多數情況下,在C#2中也可以,但類型推斷對你來說不會有太大的幫助,你必須使用匿名方法而不是lambda表達式。

但要回到起點:儘量少用try/catch。 (儘量/最後應該更頻繁,儘管通常寫成使用語句。)

+0

@Jon ahh你打我它..DAM YOU;) – 2008-11-11 06:40:05

3

您可以嘗試使用一些空驗證。我可以採取的LINQ to 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

其實你不應該拋出`NullReferenceException`。這是爲運行時保留的。你可以試試`ArgumentNullException` – 2008-11-11 07:43:59

+0

對不起。我很急的寫下了這本書。我會馬上改變它。 Thanx :) – stiduck 2008-11-11 09:14:13

2

也許你正在通過不同的語法處理異常處理的錯誤代碼?所以不要嘗試/捕捉。讓異常向上傳播。

0

我不確定C#,但是在Java-land中,您可以定義和接口所有方法,然後將其隱藏在代理對象下。你可以通過定義喜歡的事,寫更多的代碼逃跑:

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

和包羅萬象的()只會調用可運行和包裝它周圍的try-catch塊。

但是,我認爲你真正想要的是一種語言已經很好closure support。使用閉包,做你想做的事情是非常容易的。

+0

幸運的是,C#*是一種支持良好閉包的語言:)(這個問題沒有說明語言,但它可以通過代碼推斷出來,並提及IL和代表。) – 2008-11-11 08:12:03

2

對我來說,我看起來像你在問面向方面編程。我想你應該看看PostSharp。

+0

謝謝,我想這就是我想要的,你有沒有在生產代碼中使用這種方法? – 2008-11-11 08:17:39