一、TargetSite属性(public MethodBase TargetSite { get; })
System.Exception.TargetSite属性帮助我们了解引发某个异常的方法的各种信息。输出TargetSite的值将显示返回值类型、方法名称、引发异常方法的参数。
它不是只返回字符串,而是返回一个强类型的System.Reflection.MethodBase对象。
1 Console.WriteLine("Member name: {0}", e.TargetSite);//输出结果:Void Accelerate(Int32) 2 Console.WriteLine("Class defining member: {0}", e.TargetSite.DeclaringType);//输出结果:ConsoleApplication3.Car 3 Console.WriteLine("Member Type: {0}", e.TargetSite.MemberType);//输出结果:Method
说明:
1.我们使用MethodBase.DeclaringType属性值来制定引发异常的类的全称(这个例子中时ConsoleApplication3.Car)。
2.使用MethodBase对象的MemberType属性来确定引发异常的成员类型(比如属性和方法)。
二、StackTrace属性(public virtual string StackTrace { get; })
System.Exception.StackTrace属性帮助我们标识引发异常的一些列调用。需要注意的是,StackTrace的值是异常创建时自动产生的,无法为其赋值。
例:
1 catch(Exception e) 2 { 3 Console.WriteLine("Stack: {0}", e.StackTrace); 4 }
输出:
Stack: 在 ConsoleApplication3.Car.Accelerate(Int32 delta) 位置 e:\Test\ConsoleApplication3\ConsoleApplication3\Program.cs:行号 66标识这个序列的首次调用
在 ConsoleApplication3.Program.Main(String[] args) 位置 e:\Test\ConsoleApplication3\ConsoleApplication3\Program.cs:行号 18标识出错成员的具体位置
在调试装或记录制定应用程序时,这些信息都非常有用,它使我们能顺其自然地发现错误的根源。
三、HelpLink属性(public virtual string HelpLink{ get; set; })
默认情况下HelpLink属性的值是一个空字符串。如果读者需要一个有意义的值填充该属性,就要在引发System.Exception类型异常之前赋值。
例:
将上例中的Accelerate方法更新
1 public void Accelerate(int delta) 2 { 3 if (casIsDead) 4 { 5 Console.WriteLine("{0} is out of order...", PetName); 6 } 7 else 8 { 9 CurrentSpeed += delta; 10 if (CurrentSpeed >= MaxSpeed) 11 { 12 casIsDead = true; 13 CurrentSpeed = 0; 14 15 //我们需要调用HelpLink属性,因此需要在异常对象引发之前先创建一个本地变量 16 Exception ex = new Exception(string.Format("{0} has overheated!", PetName)); 17 ex.HelpLink = "http://www.CarsRus.com"; 18 throw ex; 19 } 20 else 21 { 22 Console.WriteLine("=> CurrentSpeed = {0}", CurrentSpeed); 23 } 24 } 25 }
四、Data属性(public virtual IDictionary Data { get; })
System.Exception中的Data属性允许我们使用用户提供的响应信息来填充异常对象。
更新Accelerate方法:
1 public void Accelerate(int delta) 2 { 3 if (casIsDead) 4 { 5 Console.WriteLine("{0} is out of order...", PetName); 6 } 7 else 8 { 9 CurrentSpeed += delta; 10 if (CurrentSpeed >= MaxSpeed) 11 { 12 casIsDead = true; 13 CurrentSpeed = 0; 14 15 //我们需要调用HelpLink属性,因此需要在异常对象引发之前先创建一个本地变量 16 Exception ex = new Exception(string.Format("{0} has overheated!", PetName)); 17 ex.HelpLink = "http://www.CarsRus.com"; 18 19 //填充关于错误的自定义数据 20 ex.Data.Add("TimeStamp", string.Format("The car exploded at {0}", DateTime.Now)); 21 ex.Data.Add("Cause", "You have a lead foot."); 22 throw ex; 23 } 24 else 25 { 26 Console.WriteLine("=> CurrentSpeed = {0}", CurrentSpeed); 27 } 28 }
调用:
1 static void Main(string[] args) 2 { 3 Car myCar = new Car("Zippy", 20); 4 5 try 6 { 7 for (int i = 0; i < 10; i++) 8 { 9 myCar.Accelerate(10); 10 } 11 } 12 catch (Exception e) 13 { 14 //默认情况下,data字段是空的,需要检查是否为空 15 if (e.Data != null) 16 { 17 foreach (DictionaryEntry item in e.Data) 18 { 19 Console.WriteLine("-> {0}: {1}", item.Key, item.Value); 20 } 21 } 22 } 23 }
输出:
=> CurrentSpeed = 30
=> CurrentSpeed = 40
=> CurrentSpeed = 50
=> CurrentSpeed = 60
=> CurrentSpeed = 70
=> CurrentSpeed = 80
=> CurrentSpeed = 90
-> TimeStamp: The car exploded at 2014-06-26 16:16:54
-> Cause: You have a lead foot.
说明:
Data属性非常有用,因为它允许我们打包关于“错误”的自定义信息,无须构建全新的类类型来扩展Exception基类。
结构化异常处理(二):配置异常的状态