2012-06-04 42 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