.net核心机制
1,定义异常
设计类型时,首先要想好类型的各种使用情况。类型名称通常是一个名词,例如FileStream或者StringBuilder。然后,要为类型定义属性、方法、事件等。这些成员(属性的数据类型、方法的参数、返回值等)的定义方式就是类型的编程接口。这些成员代表类或者类型实例可以执行的行动。行动成员通常用动词表示,例如Read,Write,Flush,Append,Insert 和Remove等。当行动成员不能完成任务时,就应抛出异常。
定义:异常是指成员没有完成它的名称宣称可以完成的行动。
例如:日常转账方法,from账户转账到to账户,from账户可能没有足够的资金,to账户资金可能过多,炮制账户溢出。都会导致异常情况出现。这个时候应抛出异常来通知调用者他不能完成任务。
2,异常处理机制
以下展示了异常处理机制的标注用法
private void RunMethod(){
try{
}
catch(InvalidOperationException)
{
//从InvalidOperationException恢复的代表放在这里
}
catch(IOException)
{
//从IOException恢复的代码放在这里
}
catch{
//从除了上述异常之外的其他异常恢复的代码放在这里
...
// 捕捉任何异常时,通常要重新抛出异常
throw;
}
finally{
//这里的代码总是被执行
}
}
catch块包含的是响应一个异常需要执行的代码。
finally 块包含的代码是保证会执行的代码。通常,finally快的代码执行的try块中的行动锁要求的资源清理操作。例如FileStream文件操作最终的close操作。当然try块并非一定要关联一个finally块;有的时候,try块中的代码并不需要任何清理工作。但是,如果有finally块,他必须出现在所有catch块之后。
注意:catch和finally块中的代表应该非常短,而且要有非常高的成功率,避免自己又抛出一个异常。
特别关注点:
当然catch或finally中的清理代码总是有可能失败并抛出一个异常的。如果出现这种情况,CLR的异常处理机制仍会正常运转,好像异常是在Finally块以后抛出的一样。但是出现这种情况时,CLR不会记录对应try块中抛出的第一个异常,关于第一个异常的所有信息(例如堆栈跟踪)都将丢失。这个新异常可能(而且极有可能)不会由你的代码处理,最终变成一个未处理的异常。这种情况下,CLR会终止你的进程。
3,抛出异常
如果希望定义一个异常类型层次结构,强烈建议让这个层次结构浅而宽,以创建尽量少的基类。原因是基类的主要作用就是将大量错误当作一个错误,而这通常是危险的。(想象几层大网,一层叠一层,最下边的就是基类,它要负责借助前面几层的“漏网之鱼”)。基于同样的考量,永远都不要抛出一个System.Exception对象,抛出其他任何基类异常类型时也要特别谨慎。