Effective C# Item45 : 优先选择强异常安全保证
当应用程序捕获一个异常时,代表着我们为应用程序引入了一个“具有破坏性的事件“,异常可能会对系统资源或者应用程序的状态有破坏,我们应该避免这种情况发生。
Dave Abrahams对于异常,定义了3种情况:1. 基本保证;2、强保证;3、无异常抛出。
基本保证,确保在应用程序抛出异常后,没有任何资源泄漏,并且所有对象都处于有效状态;强保证,在基本保证的基础上,又添加了“如果有一场抛出,程序状态保留不变”的条件;“无异常抛出”确保一个操作在任何情况下都不会失败,也就是说一个方法永远不会将异常抛出。通常情况下,强异常机制在“从异常中恢复”和“简化异常处理”之间提供了最好的平衡。
在C#中,由于.NET提供了垃圾回收机制,因此它可以默认提供“基本保证”,因此只有以下情况下才会需要手动释放:在拥有一个实现了IDisposable接口的资源时,跑出了一个异常。
“强异常保证”确保如果操作因为异常而中断,那么程序状态保持不变,操作或者完成或者不改变程序状态,没有中间态。
我们可以通过以下步骤来实现强异常保证。
1. 对将要修改的数据做“防御性的复制”。
2. 对这些数据的“防御性复制”进行修改,这些中间操作可能会引发异常。
3. 将临时的副本和原对象进行交换,交换操作不可能抛出任何异常。
我们可以看以下的代码。
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. 在委托链中的某个方法,如果抛出了异常,那么委托链中后面的方法就不会再执行。
异常会严重影响一个程序的控制流,在最坏的情况下,任何事情都可能发生,也可能不发生,当抛出异常时,要知道哪些发生了改变或者哪些没有发生改变的唯一方式就是实现“强类型保证”。
转载于:https://www.cnblogs.com/wing011203/archive/2010/03/01/1675789.html
Effective C# Item45 : 优先选择强异常安全保证相关推荐
- Effective Java~46. 优先选择Stream 中无副作用的函数
纯函数(pure function)的结果仅取决于其输入:它不依赖于任何可变状态,也不更新任何状态. 坏味道 // Uses the streams API but not the paradigm- ...
- Effective Java之优先使用标准的异常(六十)
Java平台类库提供了一组基本的未受检的异常,他们满足了绝大部分API的异常抛出异常. 为什么优先使用标准异常 1.它使你的API可读性更强,因为它与程序员习惯的用法一致. 2.异常类越少,程序在类装 ...
- Effective Java读书笔记五:异常
第57条:只针对异常的情况才使用异常 异常是为了在异常情况下使用而设计的,不要将它们用于普通的控制流,也不要编写迫使它们这么做的API. 下面部分来自:异常 如果finally块中出现了异常没有捕获或 ...
- [react] props.children.map和js的map有什么区别?为什么优先选择react的?
[react] props.children.map和js的map有什么区别?为什么优先选择react的? React.Children.map 能够处理未知数据类型,即使 React.childre ...
- 陈松松:制作视频优先选择这5种类型,总有一个适合你
这是我写的第88篇原创视频营销文章 陈松松,6年视频营销实战经验 万事开头难! 就看谁先能挺住! 很多朋友发现制作视频也有很多类型,不知道选择哪种最适合自己,今天我就跟大家详细分享下,当你学习之后,你 ...
- 不被消费者优先选择的,不叫品牌,叫商标
不被消费者优先选择的,不叫品牌,叫商标 周末与客户聊关于"交易成本"的问题后,对我说:真是太有对了!我公司产品的"交易成本"就非常高.我的产品非常好,各项指标都 ...
- [转]Effective C# 原则7: 选择恒定的原子值类型数据
恒定类型(immutable types)其实很简单,就是一但它们被创建,它们(的值)就是固定的.如果你验证一些准备用于创建一个对象的参数,从前面的观点上看, 你知道它在合法(valid)状态.你不能 ...
- 在线协助设计软件,figma、sketch、xd哪个才是你的优先选择
我们今天生活的环境,互联网的快速发展,新的意识形态的不断涌现,工作方式的不断变化,开放的开放.更多的行业和更多的人理解共享的概念,在这样的环境中,效率变得越来越重要.好的工具和工作方法带来先进的生产力 ...
- Spring注解依赖注入的三种方式的优缺点以及优先选择
当我们在使用依赖注入的时候,通常有三种方式: 1.通过构造器来注入: 2.通过setter方法来注入: 3.通过filed变量来注入: 那么他们有什么区别吗?应该选择哪种方式更好? 代码示例: Con ...
最新文章
- POJ2594 Treasure Exploration[DAG的最小可相交路径覆盖]
- 关于Unity中物理检测的准备
- Consul入门05 - 健康检测
- vc调用mysql数据库操作例子
- php5 php4,自动实现php4和php5环境的切换......
- leetcode 1047. 删除字符串中的所有相邻重复项(栈)
- 初识Mysql(一)
- 你需要知道的Linux 系统下外设时钟管理
- mysql 建前缀索引_MySQL_前缀索引_建立
- MongoDB 之 你得知道MongoDB是个什么鬼 MongoDB - 1
- mt950报文解析_MT700报文升级内容逐项解析
- 编译一个.cpp文件的过程
- 使用Java生成思维导图
- 【题解】洛谷 P1957 口算练习题
- keep-alive 的详细介绍
- 1608: DNA序列---复制问题 - kmp
- html:超文本标记语言的特点
- lua_pcall 函数详解
- cmd怎么切换mysql目录_mysql 移除服务,并在cmd下切换目录
- Linux 系统安装
热门文章
- QTreeWidgetItem 类的翻译
- 我拿什么融化你,冰冷的电子图书馆?
- 大学计算机软件专业生应该学什么(转)
- CVPR 2018 LSART:《Learning Spatial-Aware Regressions for Visual Tracking》论文笔记
- 在Ubuntu中使用OTB-50测试ECO模型
- 2019寒假纪中集训总结学期总结(流水账)
- linux 修改网卡mac,Linux修改
网卡物理地址(Mac Address)
- sqlserver/mysql按天,按小时,按分钟统计连续时间段数据
- 第五章 初始jQuery
- day60 Pyhton 框架Django 03