摘要:
本文以C#为编程语言,讨论了 .NET 中的异常处理方式,主要包括 try/catch 块、finally语句、Exception 对象、throw语句等主题。
本文内容
- 理解异常的基本概念
- 使用 try/catch 块处理异常
- 理解finally的意义
- 使用 Exception 对象确定异常
- 将异常返回过程调用程序
基本概念
就像其他面向对象语言一样,C#采用异常(exception)来应对程序错误和非正常情况。
异常是包含程序非正常事件信息的对象。与缺陷(bug)不同,一个bug是程序员的疏漏,它们应该在产品发布前被更正;尽管一个bug可能引发异常的抛出,你不应该完全依靠异常来处理你的bug,它至多是你测试的手段,你应该自己更正哪些bug。类似的,错误(error)是由用户操作而引起,比如在一个应该输入字母的地方用户输入了一个数字;虽然它也可能引发异常,但你应该通过校验代码(validation code)来抓住这些错误。无论何时,在可能的情况下错误都应该是能预料和能被预防的。即使你除去了所有的bug和列举了所有可能的用户错误,你仍会遇到无法预料和阻止的异常,如内存耗尽、网络崩溃。你无法预防异常,但你能处理它们,以避免它们使你的程序崩溃。
当你的程序遇到一个非正常情况,比如说内存不足,它就会引发(throw/raise)一个异常。此时,当前的过程调用将挂起,.NET 运行时(CLR)将从下至上搜索过程调用堆栈,以查找相应的异常处理程序。也就是说,如果抛出异常的代码正处于某个 Try 块中,运行时将首先使用本地的 Catch 块(如果有)来处理异常(它将执行在该位置找到的 Catch 块代码),否则这个程序段将被终止并将异常的处理权交给其调用函数;如果没有函数处理此异常(即在整个调用堆栈中没能找到适当的 Catch 块),最终运行时将会得到并处理它,并立刻将你的程序终止。
引发错误
示例为一个简单的文件打开操作并检索其长度的程序(以后几个示例的内容基本相同),示例从窗体文本框textBoxfilepath中得到文件名:
string filepath=this.textBoxfilepath.Text; long isize; FileStream fs=File.Open(filepath,FileMode.Open); isize=fs.Length; fs.Close();
有许多原因会使代码引发异常,如文件不存在,访问权限不够等等。在现在这种没有异常处理的情况下,运行时发生的任何错误会回溯到.NET运行时(CLR)