首页 > 代码库 > 结构化异常处理(四)构建自定义异常

结构化异常处理(四)构建自定义异常

一、构建一个强类型异常来表示当前问题的独特细节效果会更好。

假定要构建一个名为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键来激活代码。