捕获条款的顺序

时间:2009-07-19 00:43:00

标签: c# exception-handling

使用框架方法时,突出显示时会得到的描述将列出可能引发的异常。

如果按此顺序编写catch处理程序是否重要?例如。 SqlConnection.Open()可以抛出:

System.InvalidOperationException System.Data.SqlClient.SqlException

按顺序列出。我的捕捉处理程序应遵循此顺序吗?如果是这样,为什么?

此外,某些方法(如SqlDataAdapter.Fill())返回一个int,但如果我没有存储返回值的变量,则Visual Studio不会报告错误。为什么呢?

由于

4 个答案:

答案 0 :(得分:8)

除非catch处理程序中指定的异常之一继承自另一个处理程序中指定的另一个异常,否则顺序是无关紧要的,在这种情况下,应该首先发出更多派生的catch(或者永远不会调用它)。

运行时将按照它们列出的顺序遍历catch块,执行匹配的第一个块,因此如果您有以下内容,则只会执行第一个catch块,甚至如果抛出ArgumentException:

try
{
  throw new ArgumentException("foo");
}
catch (Exception ex)
{
}
catch (ArgumentException aex)
{
  // Will never be executed.
}

答案 1 :(得分:5)

(我同意Mitch的说法,因为它使代码更易于维护,因此按照优先顺序进行捕获。)

我还想补充一点,必须按顺序从最低子类继承到最高父类。

例如,如果要捕获System.Exceptions和System.InvalidOperationExceptions,则必须首先捕获InvalidOperationException,因为它是System.Exception的子类。如果您首先获得System.Exception的catch,那么优先级将会触发InvalidOperationException的catch块。

答案 2 :(得分:3)

您应该按照文档中列出的顺序放置捕获处理程序,但是按照特定情况的优先顺序放置。

在说,如果您正在访问SQL Server数据库并获得SQL异常,那么您的应用程序不太可能继续,因此SqlException应该是高优先级。

更新:我省略了有关异常继承顺序的部分(从大多数派生到基础),因为我错误地认为这是给定的。其他海报明确提到了这一点。

答案 3 :(得分:1)

catch的顺序并不重要,但应该注意的是,在所有派生的异常之后,应该在最后写出基本异常。

您也可以根据应用程序中可能出现的错误的优先级或出现来命令catch块

如果我们以错误的方式写作

catch (Exception ex) {
    strMessage = ex.Message.ToString();
} catch (ArgumentNullException aex) {
    strMessage = aex.Message;
}

编译器将在上述情况下报告错误,错误将是这样的 - 前一个catch子句已经捕获了这个或超类型System.Exception的所有异常。