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

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

假定要构建一个名为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 Message
20         {
21             get
22             {
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             try
10             {
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键来激活代码。

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

时间: 2024-12-11 08:35:40

结构化异常处理(四)构建自定义异常的相关文章

结构化异常处理系列

最近在项目中看到了许多自定义异常类,就想把它搞明白. 想知道为什么要这样处理?这样处理的优点是什么?自己怎么常见自己需要的自定义异常类? C#结构化异常处理是将程序中出现的错误的名称.消息和其他有用的信息都打进一个定义明确的包内. 构建一个强类型的自定义异常,这样在程序中对异常处理时就可以根据不同问题具有针对性的使用异常类,这样使用起来也更加明了,一看到就知道这里处理的是什么异常,一目了然. 下面就将学习笔记放在这里,希望大家多多指点: 结构化异常处理(一)概述 结构化异常处理(二)配置异常的状

深入研究 Win32 结构化异常处理(好多相关文章)

摘要 就像人们常说的那样,Win32 结构化异常处理(SEH)是一个操作系统提供的服务.你能找到的所有关于 SEH 的文档讲的都是针对某个特定编译器的.建立在操作系统层之上的封装库.我将从 SEH 的最基本概念讲起. Matt Pietrek 著董岩 译Victor 转载自 Xfocus 并整理 在所有 Win32 操作系统提供的机制中,使用最广泛的未公开的机制恐怕就要数结构化异常处理(structured exception handling,SEH)了.一提到结构化异常处理,可能就会令人想起

深入研究 Win32 结构化异常处理(作者博客有许多SEH的研究文章)

摘要 就像人们常说的那样,Win32 结构化异常处理(SEH)是一个操作系统提供的服务.你能找到的所有关于 SEH 的文档讲的都是针对某个特定编译器的.建立在操作系统层之上的封装库.我将从 SEH 的最基本概念讲起. Matt Pietrek 著董岩 译Victor 转载自 Xfocus 并整理 在所有 Win32 操作系统提供的机制中,使用最广泛的未公开的机制恐怕就要数结构化异常处理(structured exception handling,SEH)了.一提到结构化异常处理,可能就会令人想起

结构化异常处理(二):配置异常的状态

一.TargetSite属性(public MethodBase TargetSite { get; }) System.Exception.TargetSite属性帮助我们了解引发某个异常的方法的各种信息.输出TargetSite的值将显示返回值类型.方法名称.引发异常方法的参数. 它不是只返回字符串,而是返回一个强类型的System.Reflection.MethodBase对象. 1 Console.WriteLine("Member name: {0}", e.TargetSi

结构化异常处理(五)处理多个异常

一.多个catch块 在最简单的情形下,一个try块有一个catch块.但是在现实中,你常常会遇到包含try块的语句能够触发许多可能发生的异常的情形. 1.接之前的例子修改,假定在用户传入一个无效参数(比如小于0的值)的情况下,修改Car的Accelerate()方法还会引发一个基础类库定义的异常ArgumentOutOfRangeException. 该异常类的构造函数接收的第一个字符串参数为错误参数的名称,然后是描述该错误的信息. 代码: 1 public void Accelerate(i

结构化异常处理(一)

一.错误.bug与异常 在.NET术语命名中,“异常”解释为bug.用户输入错误和运行时错误. 二..NET异常处理的作用 理想情况下,我们希望将这个错误的名称.消息和其他的有用信息都打进一个明确的包内,这正是结构化异常处理所做的. 结构化异常处理方案的优点: 1.开发人员现在又了统一的而且对.NET领域内各种语言都通用的方式来处理错误. 2.用以引发核捕获异常的语法在不同程序集间或计算机间都是一致的. 3.我们不再是通过接收意义模糊的数字常量来确定问题,而是可以通过异常,它包含容易度读懂的问题

结构化异常处理(三)系统级异常和应用程序级异常

一.系统级异常 1.准去的说,.NET平台引发的一场应被称为系统异常.这些异常被认为是无法修复的致命错误. 2.系统异常直接派生自名为System.SystemException的基类,该基类派生自System.Exception. SystemException除了一组自定义的构造函数不添加任何功能. public class SystemException :  Exception { //各种构造函数 } 3.当一个异常类型派生自System.SystemException时,我们就能够判

[转载]深入解析结构化异常处理

尽管以前写过一篇SEH相关的文章<关于SEH的简单总结>, 但那真的只是皮毛,一直对Windows异常处理的原理似懂非懂, 看了下面的文章 ,一切都豁然开朗. 1997年文章,Windows技术的根一直没变:http://www.microsoft.com/msj/0197/exception/exception.aspx Matt Pietrek 著 董岩 译 在Win32操作系统提供的所有功能中,使用最广泛而又没有公开的恐怕要数结构化异常处理(Structured Exception Ha

第23章 SEH结构化异常处理(1)

23.1 基础知识 23.1.1 Windows下的软件异常 (1)中断和异常 ①中断是由外部硬件设备或异步事件产生的 ②异常是由内部事件产生的,可分为故障.陷阱和终止三类. (2)两种异常处理机制:SEH和VEH(WindowsXP以上新引进) (3)结构化异常处理(SEH)是Windows操作系统提供的强大异常处理功能.而Visual C++中的__try{} __finally{}和__try{} __except{}结构本质上是对Windows提供的SEH的封装. 23.1.2 SEH的