标签:
异常就是指成员没有完成它的名称所宣示的行动。
public class Girl { public string Name { get; set; } } public class Troy{ Girl girl; public void Love() { Console.WriteLine("Troy爱上了" + girl.Name); } }
上面这段代码会有异常,因为Troy去执行Love这个函数,然而其中girl根本就没有赋值。本来Troy预期完成爱一个姑娘这个行动,结果发生了异常的事情,姑娘离开了Troy。
异常要解决的问题
很多行为(比如方法和属性)很多时候都没法返回错误代码(比如void方法,构造器,属性的获取设置),但他们仍然需要报告错误,于是异常就来解决这个问题。
也就是说异常处理机制实际上是为了返回可预知的错误代码,而不是为了去捕获未知的异常让程序不报错。(这一点非常重要)
不要去让程序吞异常,不把异常暴露出来让其继续运行,反而可能使程序做出更错误的举动。(有错就改,别藏着)
那么其实我在刚学习的时候一直有个疑问,我这个系统很多人在用啊,你如果不吞异常,那报黄页不是更6?
现在我认为这并不矛盾,如果有异常就在catch后进行异常处理还原操作,然后写日志或者用一个统一的页面去提示用户出错了,而不是把黄页去给用户看。(就像你告诉别人你得胃病了,用嘴和肢体语言表述都行,你剖开自己的肚子告诉别人你有病就是你的错了啊)
.Net的异常处理机制
.Net的异常处理机制是基于windows提供的结构化异常处理机制(Structured Exception Handing,简称SEH)构建的。
异常处理的代码就不演示了,说说三大块
static void Main(string[] args) { try { FuncA(); } finally { Console.WriteLine("主函数Finally"); } Console.Read(); } static void FuncA() { try { Object obj = new DateTime(); int a = (int)obj;//这里会报System.InvalidCastException异常 } catch(InvalidDataException)//表示不匹配,然后到调用栈的上一级也就是main函数,然而main函数中的try根本就没有catch所以更谈不上什么匹配,也就是出现了一个未处理的异常 { //这里完全不会执行 } finally {//虽然有Finally说好的,不论是否异常都会执行,然而此时上面的异常没有catch到,
//所以已经异常报错了,不会再执行到这里。此时CLR会终止进程,相较于让程序继续运行造成不可预知的结果这样更好 Console.WriteLine("函数A的Finally"); } }
System.Exception类
微软规定所有CLS相容的编程语言都必须抛出和捕捉派生自该类型的异常。
一般来讲也就这个类中也就三个属性要注意:
抛出异常
抛异常需要考虑两个问题:
第一个是抛出什么Exception类型的异常。应该选择一个更有意义的类型。要考虑到调用栈中高处的代码,要知道那些代码如何判断一个方法失败从而执行得体的恢复代码。作者强烈建议异常的继承层次结构应该浅而宽,这样就可以尽量少的创建基类。而基类意味着把众多错误当做一个错误来处理。
第二个是向异常类型的构造器传递什么字符串消息。
自定义异常类
看起来自定义异常类很简单,只需要继承System.Exception类就OK了,然而实际上这是个很繁琐的事情。
因为从System.Exception类派生出来的所有类都应该是可序列化的,使它们能穿越AppDomain边界去写入日志或者数据库。而序列化就涉及到很多问题。
作者写了个泛型异常类去简化,我这里就不写了,实际上在格式上找个系统异常照着写就行了:
别忘了在自定义类上面加上[Serializable]特性。
作者的玩法更高端一点,自己建个泛型异常类继承Exception,然后将一些构造函数或者序列化函数写在这个类中。个性化的异常信息作为泛型变量T传给泛型异常类来使用,以此起到简化作用。
------未完待续,以上讲得还是些基础,接下来才会写如何去正确得使用异常处理机制---------
用可靠性换取开发效率
设计规范和最佳实践
未处理的异常
对异常进行调试
异常处理的性能问题
约束执行区域
代码协定
标签:
原文地址:http://www.cnblogs.com/vvjiang/p/5357519.html