忽略异常类型的更好方法:多个catch块与类型查询

时间:2011-01-16 08:19:13

标签: c# .net exception-handling

在某些情况下,我们希望忽略特定的异常类型(通常为ObjectDisposedException)。可以通过这两种方法实现:

try
{
    // code that throws error here:
}
catch (SpecificException) { /*ignore this*/ }
catch (Exception ex)
{
    // Handle exception, write to log...
}

try
{
    // code that throws error here:
}
catch (Exception ex)
{
    if (ex is SpecificException) { /*ignore this*/ }
    else
    {
        // Handle exception, write to log...
    }
}

这两种方法的优缺点是什么(关于性能,可读性等)?

6 个答案:

答案 0 :(得分:6)

我认为这主要是一个偏好问题,但专用的emtpy catch对我来说看起来更干净。读取代码的程序员可以假设熟悉try / catch构造,并且他们希望您将catch块从特定到一般进行排序。人们阅读try / catch构造的通常方式是浏览捕获,直到找到与他们正在寻找的匹配的东西(就像编译器那样),然后看看它做了什么。阅读器无论如何都是这样做的,所以当你有一个专门的空捕获的异常类型时,很明显它是一个特殊情况,并且你正在丢弃异常。内置类型检查逻辑OTOH要求读者找到更一般的异常分支,它可能在catch块列表中,然后读取实际逻辑以找出发生的情况。我要说这需要比空捕获更多的阅读努力。

另一点是,你应该有理由忽略异常;对于一个空的catch块,对于你和那些检查你的代码的人来说,你会忽略错误,这是很明显的 - 这很好 - 这意味着人们会注意到并且对这种潜在的陷阱有更多的意识,你会被推动添加一个解释为什么你这样做的评论。如果你将ignore-this-exception部分隐藏在处理程序逻辑中,人们可能会读过它然后想知道为什么他们的异常不会在任何地方弹出。

答案 1 :(得分:3)

catch (SpecificException) { /*ignore this*/ }

与人们可以得到的一样明确 - 但只有当你包含评论以确保清楚时,这不是忘记填写处理代码的情况。

答案 2 :(得分:2)

我会使用第二种风格的内容,但会将实际逻辑封装在另一种方法中:

try
{
    // code that throws error here:
}
catch (Exception ex)
{
    ExceptionHandling.Handle(ex);
}

并在内部检查类型

if (ex is SpecificException) { /*ignore this*/ }
else
{
        // Handle exception, write to log...
}
  1. IMO它更具可读性。
  2. 您不重复处理逻辑
  3. 如果您需要处理ObjectDisposedException,则很容易更改
  4. 谢谢, ë

答案 3 :(得分:2)

我更喜欢第一种风格,因为它更具可读性,当您针对不同的异常类型做出不同的决定时,它更适合。

try {
    // ...
} catch (IgnoreThisException) {
    // ignore this
} catch (UnableToHandleHereException) {
    throw; // this should be catched by caller
} catch (Exception e) {
    // log the rest
}

答案 4 :(得分:1)

我认为第一个显然更好。这是捕获语言提供的多个异常的常规方法。它还直接映射到CIL中的两个catch块,而第二个需要isinst

我不知道这是否会具体改善性能,但JIT应该更容易优化。

答案 5 :(得分:0)

第二种风格更好,因为你忽略异常。它比第一种风格更好地传达意图。

如果其他开发人员看到了第一个样式,他/她会想知道您是否忘记编写处理忽略异常的代码。

在表现方面,没有明显的差异。