异常处理(C# 编程指南)
更新:2007 年 11 月
C# 程序员使用 try 块来对可能受异常影响的代码进行分区,并使用 catch 块来处理所产生的任何异常。可以使用 finally 块来执行代码,而无论是否引发了异常。有时需要这样做,因为如果引发了异常,将不会执行 try/catch 构造后面的代码。try 块必须与 catch 或 finally 块一起使用,并且可以包括多个 catch 块。例如:
try
{
// Code to try here.
}
catch (SomeSpecificException ex)
{
// Code to handle exception here.
// Only catch exceptions you know how to handle.
// Never catch base class System.Exception without
// rethrowing it at the end of the catch block.
}
try
{
// Code to try here.
}
finally
{
// Code to execute after try here.
}
try
{
// Code to try here.
}
catch (SomeSpecificException ex)
{
// Code to handle exception here.
}
finally
{
// Code to execute after try (and possibly catch) here.
}
不带有 catch 或 finally 块的 try 语句将导致编译器错误。
Catch 块
catch 块可以指定要捕捉的异常类型。此类型称为“异常筛选器”,应该是从 Exception 派生的类型。一般来说,除非您确知如何处理 try 块中可能引发的所有异常,或者在 catch 块的末尾包括一条 throw 语句,否则,不要在 catch 块中指定 Exception。
具有不同异常筛选器的多个 catch 块可以串联在一起。多个 catch 块的计算顺序是从顶部到底部,但是,对于所引发的每个异常,都只执行一个 catch 块。与所引发异常的准确类型或其基类最为匹配的第一个 catch 块将被执行。如果没有任何 catch 块指定匹配的异常筛选器,则将执行不带筛选器的 catch 块(如果有的话)。需要将带有最具体的(即派生程度最高的)异常类的 catch 块放在最前面。
当下列条件为真时,应该捕捉异常:
对引发异常的原因有具体的了解,并可实现特定的恢复,例如,捕捉 FileNotFoundException 对象并提示用户输入新的文件名。
可以新建一个更具体的异常并引发该异常。例如:
int GetInt(int[] array, int index) { try { return array[index]; } catch(System.IndexOutOfRangeException e) { throw new System.ArgumentOutOfRangeException( "Parameter index is out of range."); } }
部分处理异常。例如,可以使用 catch 块向错误日志中添加项,但随后重新引发该异常,以便对该异常进行后续处理。例如:
try { // try to access a resource } catch (System.UnauthorizedAccessException e) { LogError(e); // call a custom error logging procedure throw e; // re-throw the error }
Finally 块
可以使用 finally 块清理在 try 块中执行的操作。如果存在 finally 块,它将在执行完 finally 和 finally 块之后执行。finally 块始终会执行,而与是否引发异常或者是否找到与异常类型匹配的 catch 块无关。
可以使用 finally 块释放资源(如文件流、数据库连接和图形句柄),而不用等待由运行时中的垃圾回收器来完成对象。有关更多信息,请参见using 语句(C# 参考)。
在此示例中,finally 块用来关闭在 try 块中打开的文件。注意,在关闭文件句柄之前要检查它的状态。如果 try 块没有打开该文件,则文件句柄仍然设置为 null。或者,如果成功打开文件并且没有引发异常,则 finally 块仍将执行,并且将关闭打开的文件。
System.IO.FileStream file = null;
System.IO.FileInfo fileinfo = new System.IO.FileInfo("C:\\file.txt");
try
{
file = fileinfo.OpenWrite();
file.WriteByte(0xF);
}
finally
{
// check for null because OpenWrite
// might have failed
if (file != null)
{
file.Close();
}
}
C# 语言规范
有关更多信息,请参见 C# 语言规范中的以下各章节:
16 异常
8.9.5 throw 语句
8.10 try 语句