(一)简介
错误的出现并不总是编写应用程序的人的原因,有时应用程序会因为应用程序的最终用户引发或运行代码的环境而发生错误。C#提供了异常处理机制来处理错误。
(二)异常类
在C#中,但刚出现某个特殊的异常错误条件时,就会创建(或抛出)一个异常对象。一般情况下异常没有特定的名称空间,异常类应放在生成异常的类所在的名称空间。
(三)捕获异常
.NET Framework提供了大量的预定义基类异常对象。为了在C#代码中处理可能的错误情况,一般要把程序的相关部分分成3种不同类型的代码块。
try块包含的代码组成了程序的正常操作部分,但这部分程序可能遇到某些严重的错误。
catch块包含的代码处理各种错误情况,这些错误是执行try块中的代码时遇到的。
finally块包含的代码清理资源或执行通常要在try块或catch块末尾执行的其他操作(无论是否抛出异常,finally块都会执行)。
try { //代码 } catch (Exception) { //可以设置多个catch捕捉不同的异常(捕捉顺序从上往下) } finally { //可省略 }
1、实现多个catch块
try { //代码 } catch (IOException) { //可以设置多个catch捕捉不同的异常(捕捉顺序从上往下) } catch (Exception) { //可以设置多个catch捕捉不同的异常(捕捉顺序从上往下) } finally { //可省略 }
最先编写的catch块用于处理非常特殊的错误情况,接着是比较一般的块,它们可以处理任何错误,我们没有为它们编写特定的错误处理程序。catch块的顺序很重要,如果以相反的顺序编写这两个块,代码就不会编译,因为第二个catch块是不会执行的。
2、System.Exception属性
var exception = new Exception(); exception.Data["ErrorDate"] = DateTime.Now;//添加异常的额外信息的第一种方法 exception.Data.Add("AdditionalInfo","异常附加信息");//添加异常的额外信息的第二种方法 exception.HelpLink = "excption.txt";//异常的帮助文件 exception.Source = "测试异常应用";//导致异常的应用程序名或对象名
以上为Exception的可写属性,除此以外还有可读属性。InnerException是在catch块中抛出的,它就会包含把代码发送到catch块中的异常对象;Message描述错误情况的文本;StackTrace栈上方法调用的详细信息;TargetSite描述抛出异常的方法的.NET反射对象。
3、嵌套的try块
1 try 2 { 3 //外层代码A 4 //(此处抛出异常,由外层异常处理) 5 try 6 { 7 //内层代码 8 //(此处抛出异常,如果内层异常能够处理则处理,否则由外层异常处理) 9 //注意:如果内层不能处理异常,则在执行完finally内方法后, 10 //寻找外层匹配异常处理,这个时候外层代码B没有运行 11 } 12 catch (Exception)//内层异常处理 13 { 14 //可以设置多个catch捕捉不同的异常(捕捉顺序从上往下) 15 //(此处抛出异常,由外层异常处理) 16 } 17 finally 18 { 19 //可省略 20 //(此处抛出异常,由外层异常处理) 21 } 22 //外层代码B 23 //(此处抛出异常,由外层异常处理) 24 } 25 catch (Exception)//外层异常处理 26 { 27 //可以设置多个catch捕捉不同的异常(捕捉顺序从上往下) 28 } 29 finally 30 { 31 //可省略 32 }
(四)用户定义的异常类
class Program { static void Main(string[] args) { try { //2、抛出自定义异常 throw new MyException("自定义异常信息"); } catch (MyException ex)//3、捕获自定义异常 { Console.WriteLine(ex.Message ); } } }
//1、自定义异常类 public class MyException : Exception { //将异常信息传入基类构造函数 public MyException(string message) :base(message) {} public MyException(string message,Exception innerException) : base(message,innerException) { } }
(五)调用者信息
在处理错误时,获取错误发生位置的信息。C#5.0提供了一种新功能,可以用特性和可选参数获得这些信息(定义在System.Runtime.CompilerServices)。
1 static void Main(string[] args) 2 { 3 var p = new Program(); 4 p.Log(); 5 p.SomeProperty = 33; 6 Action a = () => p.Log(); 7 a(); 8 } 9 private int someProperty; 10 public int SomeProperty 11 { 12 get { return someProperty; } 13 set { 14 this.Log(); 15 someProperty = value; 16 } 17 } 18 public void Log([CallerLineNumber] int line = -1, [CallerFilePath]string path = null, [CallerMemberName] 19 string name = null) 20 { 21 Console.WriteLine((line < 0) ? "No Line" : "Line " + line); 22 Console.WriteLine((path == null) ? "No file path" : "Line " + path); 23 Console.WriteLine((name == null) ? "No member name" : "Line " + name); 24 Console.WriteLine(); 25 }
运行以上代码,结果如下: