有些刚开始做.NET开发的程序员把异常想得很简单,认为异常无非就是try..catch...finally了,将可能发生异常的代码放置在try里面,如果发生异常用catch(Exception ex)可以一网打尽,然后finally可以做些请求的资源的清理工作。事实上,刚做开发某段时间里,我写代码的时候从来没有认真考虑过怎么去处理和利用异常提供的信息,如果在程序运行的时候抛出异常,我也只是简单地处理Exception对象的Message,然后根据Message的信息去判断BUG可能在什么地方,现在想来这无疑很低效,通过这种方式去查找隐藏比较深的BUG是不得法的。这篇文章试图穿越异常try...catch的表面,深入到.NET中异常处理的机理,以帮助您对异常有一个更好的认识,在自己的程序中能够更好地定义异常处理异常利用异常。 定义:通常异常(Exception)是指超出了你设计的程序能够正常处理范围的情况,如你定义方法给他人调用,通常会为方法做一个说明,以告诉别人你的方法能够完成什么功能,但别人调用这个方法却无法完成预定的功能时,这时候我们说方法有异常,给出异常说明。
异常的出现:我们实现自己的类时,通常会为自己的类提供一些接口(如方法,事件,属性等)以供调用者使用,如果调用者调用接口无法完成接口预定功能时,我们就必须通知调用者接口调用出错,这时候我们通常有两种方式来通知调用者。第一种是返回错误码的方式,如接口预期完成实现返回0,没有预期完成实现返回1;第二种可以使用.NET Framework提供的异常处理机制,在我们的接口没有完成预期功能的时候抛出一个派生自System.Exception类的实例,调用者可以通过捕捉这个实例进行错误处理。
System.Exception:CLS(公共语言规范)硬性规定所有面向CLR的编程语言都必须支持抛出从System.Exception派生的对象,C#编译器只允许代码派出从Exception派生的对象,所以我们用C#编写程序,毫无疑问,我们自定义的异常类必须派生自 System.Exception,否则你无法通过throw将它抛出来。所以我们在使用自定义异常之前,必须对System.Exception类有更多的了解。
System.Exception的公共方法中,除了GetBaseException(用以遍历所有内部异常组成的链表,返回最开始那个异常),其它都没有特别的,我们更多利用的是它提供的属性。(这里只说明常用的两属性)
Message
只读
String
包含一段辅助性的文本,描述异常发生的原因。在出现未处理异常时,这些信息通常会写入log。这些信息用户通常是看不见的,所以应尽量使用技术性的词汇以帮助其它开发人员修正代码。
StackTrace
只读
String
包含了调用堆栈中抛出异常的方法的名称和签名。该属性对于调试极具价值。
我们主要通过Exception的属性获取代码出错信息的描述和出错的具体位置,以方便我们快速定位BUG和进行修复。所以我平时用到最多有两个属性,一个是Message,另外一个是StackTrace。这两个属性类型都是string,通常我们将Message写入Log日志文件,TargetSite获取的是抛出异常的方法名称,而异常发生时访问StackTrace属性可以获取一个堆栈跟踪,这个堆栈跟踪描述了异常发生前调用的方法,这些信息对于我们检查异常原因和修复代码都是非常有帮助的。
|