2012-06-04 85 views
7

我有以下兩個函數,那幾乎是一樣的,唯一的區別就是一個使用func,其他的action。如果可能的話,我想將它們合併成一個函數。C#用void寫回函數的方法返回

private static void TryCatch(Action action) 
    { 
     try 
     { 
      action(); 
     } 
     catch (Exception x) 
     { 
      Emailer.LogError(x); 
      throw; 
     } 
    } 

    private static TResult TryCatch<TResult>(Func<TResult> func) 
    { 
     try 
     { 
      return func(); 
     } 
     catch (Exception x) 
     { 
      Emailer.LogError(x); 
      throw; 
     } 
    } 

回答

3

結合這兩個成一個函數在C#真的是不可能的。 C#中的void和CLR並不是一種類型,因此具有與非void函數不同的返回語義。正確實施這種模式的唯一方法是爲無效代表和非空白代表提供過載

CLR限制並不意味着在每種CLR語言中都無法做到這一點。在使用void表示不返回任何值的函數的語言中,這是不可能的。這種模式在F#中非常適用,因爲對於無法返回值的方法,它使用Unit而不是void

+0

感謝爲什麼這是不可能的解釋。 – CaffGeek

4

您可以使用您的第二個Func<T>版本來實現Action方法,方法是將Action包裝在一個lambda表達式中。這消除了一些重複的代碼。

private static void TryCatch(Action action) 
{ 
    Func<object> fun => 
     { 
      action(); 
      return null; 
     }; 
    TryCatch(fun); 
} 

話雖這麼說,有參與做這個額外的開銷,所以就個人而言,我可能會離開它,你目前擁有的方式,來實現(特別是考慮到你原來的版本如何發生的短期和簡單的是在這個案例)。

+0

+1請參閱我的答案以獲取其他語法。 –

+0

謝謝,像我建議我會保持原樣。吮吸我實際上無法將它縮減爲單一功能。 – CaffGeek

+0

@查德否 - 你可以把它作爲一行 - 我把它分成兩個,所以你可以看到/理解發生了什麼,但你的方法很短,我會保持原樣。沒有辦法消除方法超載,但。 –

1

我這樣做@ReedCopsey建議。

這是我發現的最簡單的語法:

private static void TryCatch(Action action) 
{ 
    TryCatch(() => { action(); return 0; }); 
} 
+0

如果你需要傳遞參數給Func,你會怎麼做? – Nicknow