结构化异常处理

学习目标:

了解异常处理的基本知识

掌握如何抛出和捕获异常

理解嵌套try语句使用

了解掌握异常类

理解finally块

异常处理的基本知识

结构化异常处理测试特定的代码段,并在发生异常处理时改变错误情况或意外行为。

抛出和捕获异常

抛出和捕获异常是由try/catch/finally语句处理的,是异常处理的主要机制。

在C#处理异常时,需要在代码块中关注两个部分:一是可能导致异常的代码段(通常称为抛出异常),二是当执行过程中发生异常时将要执行的代码段(通常称为捕获异常)。

try/catch/finally语句块的基本语法如下:

            try

            {

                //可能产生异常的代码块

            }

            catch (Exception e)

            {

                //对异常进行处理的代码段

            }

            finally

            {

                //最终执行的代码块(无论是否产生异常,都会执行)

         }

如果没有错误发生,程序就会正常执行。如果发生异常,公共语言库将找到此代码最近一层的try块,而不用运行任何附加代码块。然控制传递到匹配的catch块2(如果有),并传递到关联的finally块。

如果发生异常,代码就会执行一定的操作,称为“抛出一个异常”。抛出一个异常就是实例化对象,并将其抛出,如下所示:

throw new Exception();

上面的语句实例化了Exception类的一个异常对象,在try中遇到throw语句,就会查找与这个try块对应的catch块。如果有多个对应的catch块,那么就会检查与catch块对应的异常类,确定正确的catch块。当抛出一个Exception对象时,程序会跳转到下面的catch块上:

catch(Exception e)

{

   //处理异常代码

}

下面举例说明如何抛出和捕获一个异常。在示例中,定义3个整形变量,当使用0作为除数时,将会发生异常,代码如下:  

View Code
 1 class Program
2 {
3 static void Main(string[] args)
4 {
5 int a = 0;
6 int b = 10;
7 int c = 0;
8 try
9 {
10 a = b / c;
11 }
12 catch (Exception e)
13 {
14 Console.WriteLine("发生异常:{0}", e.Message);
15 }
16 finally
17 {
18 Console.ReadLine();
19 }
20 }
21 }

在上述代码中,当除数为0时抛出异常,语句块catch(Exception e)将成捕获该异常。

运行结果如下:

try-catch错误处理表达式允许将任何可能发生异常情形的程序代码放在try块进行监控,真正处理错误异常的程序代码则被放置在catch块中,一个try块可对应多个catch块,举例说明如何使用多个catch快捕捉多个异常,代码如下:

View Code
 1 class myclass
2 {
3 static void ProcessString(string str)
4 {
5 if (str == null)
6 {
7 throw new ArgumentNullException();
8 }
9 }
10 static void Main(string[] args)
11 {
12 Console.WriteLine("输出结果为:");
13 try
14 {
15 string str = null;
16 ProcessString(str);
17 }
18 catch (ArgumentNullException e)
19 {
20 Console.WriteLine("第一个异常:{0}", e.Message);
21 }
22 catch (Exception e)
23 {
24 Console.WriteLine("第二个异常:{0}", e.Message);
25 }
26 finally
27 {
28 Console.ReadLine();
29 }
30 }

本例中通过catch语句块进行捕获异常,分别是ArgumentNullException异常和Exception异常。

运行结果为:

注意:如果没有catch语句块,程序会异常终止,使用不带参数的catch子句4,则可以捕获任何异常类型。

嵌套try语句:try语句允许嵌套,语句如下:

View Code
 1          try
2 {
3     //代码块1
4         try
5 {
6 //代码块2
7 }
8 catch
9 {
10 //代码块3
11 }
12 finally
13 {
14 // 最终代码
15         }
16 //代码块4
17 }
18 catch
19      {
20       //异常处理
21 }
22    finally
23 {
24 // 最终代码
25     }

如果异常在外层的try块中抛出,异常由外层的catch块捕获,并执行外层的finally块。如果异常在内层的try块(代码块2)中抛出,且有一个合适的内层catch块处理该异常,执行内层的finally块之后,继续执行外层的try块(标记为4代码块)。

主要的异常类

System.Exception类是其他异类的基类。System.Exception表示应用程序执行期间发生的错误。大多数异常对象都是Exception的某个派生类的实例。不过,任何从Object类派生的对象都可以作为异常引发。

Exception 类成员的使用:

View Code
 1 class exception
2 {
3 static void Main(string[] args)
4 {
5 try
6 {
7 Exception myEx = new Exception("原始异常");
8 throw myEx;
9 }
10 catch (Exception ex)
11 {
12 Console.WriteLine("异常类型:{0}", ex.GetType().ToString());//GetType方法获取当前实例的运行时类型,ToString方法用于创建并返回当前异常的字符串表示形式

13 Console.WriteLine("异常信息:{0}", ex.Message);//Message获取描述当前异常的消息

14 Console.WriteLine("堆栈跟踪:{0}", ex.StackTrace);//StackTrace用于获取当前异常发生时调用堆栈上方法的信息,有助于跟踪抛出异常的方法    

15 Console.WriteLine("应用程序名称:{0}", ex.Source);//Source用于获取或设置导致错误的应用程序或对象的名称

16 }
17 finally
18 {
19 Console.ReadLine();
20 }
21 }
22 }

运行程序,结果输出如下:

抛出预定义异常:也就是抛出内部异常类的对象

自定义异常:自定义的异常在异类中扮演一个非常重要的角色,建立一个自定义异常类,继承于ApplictionException类,

//自定义异常类

View Code
 1 class numException : ApplicationException
2 {
3 public void printError()
4 {
5 Console.WriteLine("输入的数小于1或者大于9,请重新输入!!");
6 }
7 }
8 class CustomException
9 {
10 static void Main(string[] args)
11 {
12 string num;
13 do
14 {
15 Console.WriteLine("请输入一个数,输入'exit'退出程序!");
16 num=Console.ReadLine();
17 System.Text.RegularExpressions.Regex rx=new System.Text.RegularExpressions.Regex (@"^[1-
18 9]$");//使用正则表达式判断
19 try
20 {
21 if (rx.IsMatch(num))
22 {
23 for(int i=0;i<10;i++)
24 {
25 Console.WriteLine("{0}*{1}={2}",i,num,i*Convert.ToInt32(num));
26 }
27 }
28 else
29 {
30 //抛出异常错误
31 throw new numException ();
32 }
33 //捕获异常
34 }
35 catch (numException ex)
36 {
37 ex.printError();
38 Console.WriteLine("异常类型:{0}"ex.GetType().ToString());
39 }
40 }while (!num.ToLower().Equals("exit"));
41 }
42 }

输出结果:

finally

发生异常时,执行将终止,并且交给最近的异常处理程序。Finally块可以确保发生异常时执行所有的清理工作

finally块工作方式:

View Code
 1 class myFinally
2 {
3 static void Main(string[] args)
4 {
5 int[] array1 ={ 0, 0 };
6 int[] array2 ={ 0, 0 };
7 try
8 {
9 Array.Copy(array1, array2,-1);
10 }
11 catch (ArgumentOutOfRangeException e)
12 {
13 Console.WriteLine("Error:{0}",e);
14 }
15 finally
16 {
17 Console.WriteLine("总是执行finally块");
18 }
19 Console.ReadLine();
20 }
21 }

 运行程序,不管是否发生异常,finally块都会执行,结果如下:

注意:finally块必须和try/catch快一起使用,不管是否发生异常,finally块都将保证运行

 


 


 


 

 

 

 

 



 

 

 

 

 

 

 

posted @ 2012-01-27 16:18  翼灵绝  阅读(499)  评论(0编辑  收藏  举报