• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Effective C# Item45 : 优先选择强异常安全保证

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

    当应用程序捕获一个异常时,代表着我们为应用程序引入了一个“具有破坏性的事件“,异常可能会对系统资源或者应用程序的状态有破坏,我们应该避免这种情况发生。

    Dave Abrahams对于异常,定义了3种情况:1. 基本保证;2、强保证;3、无异常抛出。

    基本保证,确保在应用程序抛出异常后,没有任何资源泄漏,并且所有对象都处于有效状态;强保证,在基本保证的基础上,又添加了“如果有一场抛出,程序状态保留不变”的条件;“无异常抛出”确保一个操作在任何情况下都不会失败,也就是说一个方法永远不会将异常抛出。通常情况下,强异常机制在“从异常中恢复”和“简化异常处理”之间提供了最好的平衡。

    在C#中,由于.NET提供了垃圾回收机制,因此它可以默认提供“基本保证”,因此只有以下情况下才会需要手动释放:在拥有一个实现了IDisposable接口的资源时,跑出了一个异常。

    “强异常保证”确保如果操作因为异常而中断,那么程序状态保持不变,操作或者完成或者不改变程序状态,没有中间态。

    我们可以通过以下步骤来实现强异常保证。

    1. 对将要修改的数据做“防御性的复制”。

    2. 对这些数据的“防御性复制”进行修改,这些中间操作可能会引发异常。

    3. 将临时的副本和原对象进行交换,交换操作不可能抛出任何异常。

    我们可以看以下的代码。

 

代码
1 public void PhysicalMove( string title, decimal newPay )
2 {
3 // Payroll data is a struct:
4 // ctor will throw an exception if fields aren't valid.
5   PayrollData d = new PayrollData( title, newPay,
6 this.payrollData.DateOfHire );
7
8 // if d was constructed properly, swap:
9   this.payrollData = d;
10 }

    下面来讨论“无异常抛出保证”,即方法一致运行,不会有异常抛出。在大部分情况下,这样做是不现实的,但是在以下情况下,还是需要使用“无异常抛出保证”:

 

    1. 对象的终结器,如果在这里抛出异常,程序就会就此中断,而不再执行其他非托管资源的清理工作。

    2. 对象的Dispose方法,如果在这个方法中抛出异常,那么系统可能会产生两个异常,.NET环境会丢弃第一个异常,并抛出一个新的异常,在程序的任何地方,我们都无法捕获最初的那个异常,因为它被系统“吞掉”了,这会极大的增加错误处理的复杂度。

    2. 在委托链中的某个方法,如果抛出了异常,那么委托链中后面的方法就不会再执行。

 

    异常会严重影响一个程序的控制流,在最坏的情况下,任何事情都可能发生,也可能不发生,当抛出异常时,要知道哪些发生了改变或者哪些没有发生改变的唯一方式就是实现“强类型保证”。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
AndroidNDK使用第一步,编译c文件,声明jni并调用。发布时间:2022-07-13
下一篇:
C#动态调用DLL发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap