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


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

        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. 在委托链中的某个方法,如果抛出了异常,那么委托链中后面的方法就不会再执行。

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

  • 相关阅读:
    C#winformchart控件曲线和悬停显示
    Skylake系列显卡参数
    《价值》
    hash碰撞
    电子钥匙功能测试
    数字证书编码ASN.1
    实验一 密码引擎1OpenEulerOpenSSL编译
    后门原理与实践
    PC平台逆向破解实验报告
    实验一 密码引擎0OpenEuler系统安装
  • 原文地址:https://www.cnblogs.com/wing011203/p/1675789.html
Copyright © 2020-2023  润新知