C#尝试捕获模式帮助

时间:2011-02-23 22:38:18

标签: c# .net try-catch design-patterns

我们总是需要在我们的代码中尝试catch,它会像

一样变得难看
public void foo()
{
  try
  {
    DoSomething();
  }
  catch(Exception e)
  {
     //do whatever with e
  }
}

public int FooReturnInt()
{
  try
  {
     return IntAfterSomeCalculation();
  }
  catch(Exception e)
  {
    //do exactly whatever with e as foo()
  }
}

想象一下,我们有一个庞大的类,有很多像这样的公共函数,我们必须在每个函数中应用相同的try catch。

理想情况下,由于try catch部分是相同的,我们可以传递Func<>作为辅助函数的参数,它执行类似

的操作
public void TryCatch(Func<something> theFunction)
{
  try
  {
    theFunction();
  }
  catch(Exception e)
  {
    //processthe common exception        
  }
}

然后我想这会整理我的代码很多,现在的问题是如何正确编写这个函数?此函数的返回类型取决于函数的返回类型。

5 个答案:

答案 0 :(得分:20)

如果确实认为需要这样做,您可以使用:

public T TryCatch<T>(Func<T> theFunction)
{
  try
  {
    return theFunction();
  }
  catch(Exception e)
  {
    // You'll need to either rethrow here, or return default(T) etc
  }
}

但是,我一般会反对它。您真的确定您需要所有这些方法中的try / catch块吗?通常,不应该是多个try / catch块,除非catch只包装异常并重新抛出...例如,在C#中甚至比在Java中更少见。

当你可以正常地处理它或者你需要阻止进程因为一个请求失败(例如)而爆炸时,通常应该捕获异常。我倾向于写很少的捕获块 - 我真的可以从错误中恢复起来是相对罕见的:)

我怀疑这种方法会导致调试时间变得非常困难。 可能仍然值得做,但你应该先仔细考虑利弊。

答案 1 :(得分:8)

使用catch块有三个原因:

1因为可能有例外。

这是错误的原因。

2因为你可以以某种方式处理异常。

这是正确的理由。

3因为您想要添加和/或隐藏详细信息

这个 catch&amp;包裹,涉及重新投掷,并不是真正的捕获。

这里的主要思想是不熟悉异常处理的程序员倾向于使用(方式)过多的catch块。你似乎属于这一类。

答案 2 :(得分:7)

虽然您可以使用帮助器/包装器方法,但您不应该以这种方式构建代码。看起来你正在尝试像返回成功/错误代码的旧系统一样使用try / catch。您的公共函数实际上应该抛出相应类型的异常,并且API的使用者应该在某种程度上使用try / catch来管理异常条件。

try / catch异常机制旨在通过允许异常“渗透”调用堆栈直到找到处理程序,使开发人员不必从代码内部链接返回代码。 (唯一一次看到异常的时候是一系列调用中的任何方法未对其进行处理。)无论如何,这里是decent place to start on this topic

这是一篇"rules of thumb"博客文章,比MSDN文章更容易理解。 another link内容更为简短。

摘自上一个链接:

  
      
  1. 不要抓住你无法处理的例外
  2.   
  3. 永远不要吞下例外
  4.   
  5. 您的代码应具有比Try / Catch
  6. 更多的Try / Finally(或使用)   
  7. 永远不要抛出/捕获新的异常()(太宽泛的类)而不是尝试   thow \ catch一个更加派生的异常   (ArgumentNullException等)
  8.   
  9. 当重新抛出异常时使用throw;抛出ex;这个   将阻止堆栈跟踪   重置
  10.   
  11. 在编写库与应用程序时,我永远不会抓到它   期待,除非我能确定   处理它
  12.   
  13. 使用逻辑来控制程序的流程而不是异常,   检查NULL而不是catch   ArgumentNullException
  14.   

第6号直接适用于您的情况。

答案 3 :(得分:0)

在我看来,所有方法中的所有尝试捕获并不难看,并且不是要试图避免的东西。不要认为catch块总是会这样做,在某些情况下会记录并抛出,在其他情况下会处理异常,在其他情况下你根本不需要catch。

如果你总是以你想要做的方式做,你甚至可能弄乱堆栈跟踪,日志文件可以帮助你减少找出真正的错误。

答案 4 :(得分:0)

你真的需要在每种方法中捕获异常吗?只要在某个地方处理异常,方法就可以抛出异常。

仔细研究您的应用程序的体系结构,并询问是否有一些点可以解决“冒泡”的异常问题。把它们放在那里。