C#中如何处理异常
2012-08-12 16:21
120 查看
throw语句
在学习如何处理异常之前,我们先介绍一下throw语句。
throw语句抛出一个异常:
throw expression
带有表达式的throw语句抛出的异常是在计算这个表达式时产生的。这个表达式必须表示一个System.Exception类型或它的派生类型的值。如果对表达式的计算产生的结果是null,则抛出的将是一个NullReferenceException异常。
不带表达式的throw语句我们稍后再介绍。
异常处理语句
异常是由try语句来处理的。
try语句提供了一种机制来捕捉块执行过程中发生的异常。以下是它的三种可能的形式:
●try-catch(s)
●try-finally
●try-catch(s)-finally
在介绍try语句之前,我们先介绍一个重要的概念:异常传播。当一个异常被抛出以后,程序将控制权转移给try语句中第一个能够处理该异常的catch子句。这个从异常抛出到控制转移给合适的异常处理语句的过程就叫做异常传播。
异常传播包括重复执行以下步骤,直到找到一个与该异常相匹配的catch子句。
(1).由里层到外层的执行每一个包围抛出点(异常被抛出的最初位置)的try语句。
●如果当前的try块包含一或多条catch子句,那么将按照这些子句的出现顺序对它们逐一检查以定位适合该异常的处理。所谓适合该异常的处理也就是第一个定义了该异常类型或其基类型的catch语句,异常传播也就结束了,程序控制转移到该catch语句执行。
●否则,如果当前的try块含有finally块的话,就执行finally块。如果该块又抛出一个异常,则当前处理的异常被终止。如果没有,则当finally块执行完成以后,再继续异常的处理。
(2).如果当前的成员函数调用中没有定位异常处理,则调用终止。并且在该成员函数调用点将该异常抛给调用者,重复执行上一步。
(3).如果该异常终止了当前线程或进程的所有成员函数调用,则说明该线程或进程中不存在对异常的处理,它将自行终止。
下面让我们回到try语句
如果catch语句中指定了一个类类型,则它必须是System.Exception类型或它的派生类型。如果同时指定了类类型和标识符,就是声明了一个异常变量。异常变量相当于一个作用范围为整个catch块的局部变量。在catch块的执行过程中,异常变量描述了当前正在处理的异常。如果想引用异常对象(其中包括很多重要的错误信息),就必须定义异常变量。
在一个catch块中,可以用不含表达式的throw语句将该catch块捕捉到的异常再次抛出,对于异常变量的分配不会改变两次抛出的异常。
既没有定义异常类型也没有定义异常变量的catch子句称做一般catch子句。该catch子句一般在事先不能确定会发生什么样的异常的情况下使用。一个try语句中只能有一个一般catch子句,而且如果有的话,该catch子句必须排在其它catch子句的后面。
尽管throw语句(含表达式)只能抛出System.Exception类型或它的派生类型的异常,但其它语句并不受该规则限制,因而可以抛出其它类型的异常。比如用一般catch语句就可以捕捉这一类异常,然后利用一个不含表达式的throw语句就可将其再次抛出。
由于寻求异常的处理是通过按照catch子句出现的顺序逐一检查catch子句,因此如果有一个catch子句定义的异常类型与比它先出现的catch子句定义的类型相同或是它的派生类型,就会发生错误。下面的例子中我们演示了try-catch语句的使用以及再次抛出异常。
程序清单8-9:
F方法捕捉到了一个异常,向控制台写了一些诊断信息,改变异常变量的内容,然后将该异常再次抛出。这个被再次抛出的异常与最初捕捉到的异常是同一个。因此程序的输出结果如下:
Exception in F:G
Exception in Main:G
当try语句执行完成后,finally块中的语句必将被执行。不论是否会发生由以下原因导致的程序控制转移:
●普通操作的结果;
●执行break,continue,goto,或return语句的结果;
●将异常传播到语句之外的结果。
我们用一个例子来证明finally语句的运行。
程序清单8-10:
该程序的输出结果为:
try
finally
leave
由此可见,finally子句总能被执行。因此我们可以利用try-finally来清除异常。
如果在执行finally块时抛出了一个异常,这个异常将被传播到下一轮try语句中去。如果在异常传播过程中又发生了一个异常,那么这个异常将被丢失。
最后,由于我们对待异常的态度往往是:捕捉、清除、继续执行程序,因此我们需要在程序中使用try-catch(s)-finally结构。
下面的例子计算函数值
其中第一个try语句捕捉负数开根号的异常,并与第二个catch语句配合达到取绝对值的目的。
本文来自编程入门网:http://www.bianceng.cn/Programmi
4000
ng/csharp/200709/4415_2.htm
在学习如何处理异常之前,我们先介绍一下throw语句。
throw语句抛出一个异常:
throw expression
带有表达式的throw语句抛出的异常是在计算这个表达式时产生的。这个表达式必须表示一个System.Exception类型或它的派生类型的值。如果对表达式的计算产生的结果是null,则抛出的将是一个NullReferenceException异常。
不带表达式的throw语句我们稍后再介绍。
异常处理语句
异常是由try语句来处理的。
try语句提供了一种机制来捕捉块执行过程中发生的异常。以下是它的三种可能的形式:
●try-catch(s)
●try-finally
●try-catch(s)-finally
在介绍try语句之前,我们先介绍一个重要的概念:异常传播。当一个异常被抛出以后,程序将控制权转移给try语句中第一个能够处理该异常的catch子句。这个从异常抛出到控制转移给合适的异常处理语句的过程就叫做异常传播。
异常传播包括重复执行以下步骤,直到找到一个与该异常相匹配的catch子句。
(1).由里层到外层的执行每一个包围抛出点(异常被抛出的最初位置)的try语句。
●如果当前的try块包含一或多条catch子句,那么将按照这些子句的出现顺序对它们逐一检查以定位适合该异常的处理。所谓适合该异常的处理也就是第一个定义了该异常类型或其基类型的catch语句,异常传播也就结束了,程序控制转移到该catch语句执行。
●否则,如果当前的try块含有finally块的话,就执行finally块。如果该块又抛出一个异常,则当前处理的异常被终止。如果没有,则当finally块执行完成以后,再继续异常的处理。
(2).如果当前的成员函数调用中没有定位异常处理,则调用终止。并且在该成员函数调用点将该异常抛给调用者,重复执行上一步。
(3).如果该异常终止了当前线程或进程的所有成员函数调用,则说明该线程或进程中不存在对异常的处理,它将自行终止。
下面让我们回到try语句
如果catch语句中指定了一个类类型,则它必须是System.Exception类型或它的派生类型。如果同时指定了类类型和标识符,就是声明了一个异常变量。异常变量相当于一个作用范围为整个catch块的局部变量。在catch块的执行过程中,异常变量描述了当前正在处理的异常。如果想引用异常对象(其中包括很多重要的错误信息),就必须定义异常变量。
在一个catch块中,可以用不含表达式的throw语句将该catch块捕捉到的异常再次抛出,对于异常变量的分配不会改变两次抛出的异常。
既没有定义异常类型也没有定义异常变量的catch子句称做一般catch子句。该catch子句一般在事先不能确定会发生什么样的异常的情况下使用。一个try语句中只能有一个一般catch子句,而且如果有的话,该catch子句必须排在其它catch子句的后面。
尽管throw语句(含表达式)只能抛出System.Exception类型或它的派生类型的异常,但其它语句并不受该规则限制,因而可以抛出其它类型的异常。比如用一般catch语句就可以捕捉这一类异常,然后利用一个不含表达式的throw语句就可将其再次抛出。
由于寻求异常的处理是通过按照catch子句出现的顺序逐一检查catch子句,因此如果有一个catch子句定义的异常类型与比它先出现的catch子句定义的类型相同或是它的派生类型,就会发生错误。下面的例子中我们演示了try-catch语句的使用以及再次抛出异常。
程序清单8-9:
using System; class Test { static void F(){ try{ G(); } catch(Exception e){ Console.WriteLine("Exception in F:"+e.Message); e=new Exception("F"); throw; } } static void G(){ throw new Exception("G"); } static void Main(){ try{ F(); } catch(Exception){ Console.WriteLine("Exception in Main:"+e.Message); } } }
F方法捕捉到了一个异常,向控制台写了一些诊断信息,改变异常变量的内容,然后将该异常再次抛出。这个被再次抛出的异常与最初捕捉到的异常是同一个。因此程序的输出结果如下:
Exception in F:G
Exception in Main:G
当try语句执行完成后,finally块中的语句必将被执行。不论是否会发生由以下原因导致的程序控制转移:
●普通操作的结果;
●执行break,continue,goto,或return语句的结果;
●将异常传播到语句之外的结果。
我们用一个例子来证明finally语句的运行。
程序清单8-10:
using System; class Test { public static void Main() { try { Console.WriteLine("try"); goto leave; } finally { Console.WriteLine("finally"); } leave: Console.WriteLine("leave"); } }
该程序的输出结果为:
try
finally
leave
由此可见,finally子句总能被执行。因此我们可以利用try-finally来清除异常。
如果在执行finally块时抛出了一个异常,这个异常将被传播到下一轮try语句中去。如果在异常传播过程中又发生了一个异常,那么这个异常将被丢失。
最后,由于我们对待异常的态度往往是:捕捉、清除、继续执行程序,因此我们需要在程序中使用try-catch(s)-finally结构。
下面的例子计算函数值
float x,y,z; try{ z=Math.Sqrt(x*x-y*y); } catch{ z=Math.Sqrt(y*y-x*x); } finally{ z=z+x; }
其中第一个try语句捕捉负数开根号的异常,并与第二个catch语句配合达到取绝对值的目的。
本文来自编程入门网:http://www.bianceng.cn/Programmi
4000
ng/csharp/200709/4415_2.htm
相关文章推荐
- C#.NET--如何处理程序的未捕获异常
- 如何处理C#的HttpWebResponse的GetResponse中的超时异常
- C# 如何处理抛出的异常,或者已知的错误
- C# 如何处理抛出的异常,或者已知的错误
- Head First C# 中文版 第10章 异常处理 page454
- 如何在C#中自定义自己的异常
- 异常?C语言程序中我们如何管控(处理)运行期间的运行异常
- C#中异常处理语句Finally
- C#调用axix2发布的Web服务(参数为int时,异常:未处理 System.Web.Services.Protocols.SoapException Message="unknown
- 如何解决C#导出excel异常来自 HRESULT:0x800A03EC的方法
- 以WebBrowser.DocumentCompleted 事件为例,说明用C#如何完成事件的订阅处理。
- C#中的异常处理【转载】
- Android 如何处理崩溃的异常
- 如何在Application中进行异常处理
- 天轰穿C# -vs2010 - 03C#的异常处理之编写更高质量的代码[原创]
- 在C#中利用Keep-Alive处理Socket网络异常断开的方法
- 如何使用Spring优雅地处理REST异常
- C#和java的异常处理性能对比
- Java如何将处理完异常之后的程序能够从抛出异常的地点向下执行?
- 解析C#中断言与异常的应用方式及异常处理的流程控制