首页 > 代码库 > 结构化异常处理(四)构建自定义异常
结构化异常处理(四)构建自定义异常
一、构建一个强类型异常来表示当前问题的独特细节效果会更好。
假定要构建一个名为CarIsDeadException的自定义异常来表示加速注定要损坏的汽车的错误。
1.创建一个派生自System.Exception/System.ApplicationException的新类(按照约定,所有的一场类均应以“Exception”后缀结束,这是.NET的最佳实践)。
1 namespace CustomException 2 { 3 public class CarIsDeadException : ApplicationException 4 { 5 private string messageDetails = String.Empty; 6 public DateTime ErrorTimeStamp { get; set; } 7 public string CauseOfError { get; set; } 8 9 public CarIsDeadException() { }10 11 public CarIsDeadException(string message, string cause, DateTime time)12 {13 messageDetails = message;14 CauseOfError = cause;15 ErrorTimeStamp = time;16 }17 18 //重写Exception.Message属性19 public override string Message20 {21 get22 {23 return string.Format("Car Error Message: {0}", messageDetails);24 }25 }26 }27 }
2.引发异常
从Accelerate()引发异常很直接,只需分配、配置和引发一个CarIsException类型,而不是通过System.Exception异常。
1 public void Accelerate(int delta)2 {3 ...... 4 5 CarIsDeadException ex = new CarIsDeadException(string.Format("{0} has overheated!", PetName), "You have a lead foot", DateTime.Now);6 ex.HelpLink = "http://www.CarsRus.com"; 7 throw ex;8 ......9 }
3.捕获异常
1 namespace CustomException 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 Car myCar = new Car("Rusty", 90); 8 9 try10 {11 myCar.Accelerate(50);12 }13 catch (CarIsDeadException e)14 {15 Console.WriteLine(e.Message);16 Console.WriteLine(e.ErrorTimeStamp);17 Console.WriteLine(e.CauseOfError);18 }19 }20 }21 }
通常情况下,仅需在出现错误的类与该错误关系紧密时才需要创建自定义异常(例如,一个自定义文件类引发许多文件相关的错误,一个Car类引发许多汽车相关的错误,一个数据访问对象引发关于特定数据库表的错误)。这样我们就能使调用者逐个地处理众多的异常。
二、改进
为了配置自定义错误信息,当前的CarIsDeadException类重写了System.Exception.Message属性,并提供两个自定义属性来说明其他数据。
事实上,不要重写Message虚属性,而只需要将传入的信息按以下方式传递给父对象的构造函数:
1 namespace CustomException 2 { 3 public class CarIsDeadException : ApplicationException 4 { 5 public DateTime ErrorTimeStamp { get; set; } 6 public string CauseOfError { get; set; } 7 8 public CarIsDeadException() { } 9 10 //将信息传递给父类对象构造函数11 public CarIsDeadException(string message, string cause, DateTime time)12 :base(message)13 {14 CauseOfError = cause;15 ErrorTimeStamp = time;16 }17 }18 }
很多情况下,自定义异常类的作用并不是提供继承基类之外附加的功能,而是提供明确标识错误种类的强命名类型,因此客户会为不同类型的异常提供不同的处理程序了逻辑。
三、构建一个严谨规范的自定义异常类
1.继承自Exception/ApplicationException类;
2.有[System.Serializable]特殊标记;
3.定义一个默认的构造函数;
4.定义一个设定继承的Message属性的构造函数;
5.定义一个处理“内部异常”的构造函数;
6.定义一个处理类型序列化的构造函数。
例:
1 [Serializable] 2 public class CarIsDeadException : ApplicationException 3 { 4 public CarIsDeadException() { } 5 public CarIsDeadException(string message) 6 :base(message) 7 { 8 9 }10 public CarIsDeadException(string message, System.Exception inner)11 :base(message ,inner)12 {13 14 }15 protected CarIsDeadException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)16 :base(info, context)17 {18 19 }20 ......21 }
Visual Studio提供了一个叫做“Exception”的代码段模板,它能自动生成一个新的遵循.NET最佳实践的异常类。输入“exc”并连按两次Tab键来激活代码。