C#中使用try-catch捕获异常的最佳实践是什么?

3
假设我需要运行 methodA,但是 methodA 将抛出 FormatException 异常。
如果我写了下面这段代码块:
try
{
    methodA();
}
catch (Exception ex)
{
    methodB();
}
catch (FormatException ex)
{
    methodC();
}

如果知道FormatException也是一种异常,因此会进入methodB的catch块中,那么它是否仍会运行methodC呢?

还是更好地这样写:

try
{
    methodA();
}
catch (Exception ex)
{
    if(ex is FormatException)
    {
        methodC();
    } else
    {
        methodB();
    }
}

3
捕获异常时,顺序很重要。 - juharr
2
你的第一个示例更好,但catch块的顺序应始终从最具体到最不具体。因此,最后一个catch块应该捕获Exception。 - rmn36
你所提议的第二种方法是最好的。这里有一个类似问题的示例 - TestWell
1
@TestWell 如果你对每种类型的异常采取不同的处理方式,那么就不会出现这种情况。 - juharr
1
@TestWell 完全没有必要捕获通用异常,然后测试类型。 - Dave Zych
2个回答

10

不会运行 methodC,但如果你交换你的 catch 的顺序,就会运行:

不,它永远不会运行 methodC,但如果您交换catch的顺序,它将运行:

返回结果:

不会运行 methodC,但如果你交换你的 catch 的顺序,就会:

try
{
    methodA();
}
catch (FormatException ex)
{
    methodC();    
}
catch (Exception ex)
{
    methodB();
}

引用MSDN的话:

在同一个try-catch语句中使用多个特定catch子句是可能的。在这种情况下,catch子句的顺序很重要,因为catch子句按顺序进行检查。在捕捉较不具体的异常之前,先捕捉更具体的异常。如果按顺序排列catch块,以至于后续块永远无法到达,则编译器会产生错误。


1

根据特定的异常,catch块总是会被执行。

所有的异常都派生自System.Exception类,因此它应该出现在你的catch块的最后。

所有其他的catch块应该是你预设的特定异常类(在你的情况中为FormatException),可能会被你的方法调用。

Dave的回答是一个完美的例子,如果你的catch块中的异常有一些层次关系,最好按照相反的层次顺序重新排序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接