巧用Using跳过异常捕获

简介:

前言

    这里主要说一个使用using躲过异常的小技巧。

    我原来就遇到过类似的问题好几次了,也没想到办法,直接有一天,调试得实在受不了了,才认真想了以下的解决方案。


问题

    原来的代码是这样的:

public abstract class Command : RoutedUICommand
{
    private bool _isExecuting = false;

    public void Execute(CommandContext commandContext)
    {
        this._isExecuting = true;
        try
        {
            OnExecute(commandContext);
        }
        catch
        {
            throw;
        }
        finally
        {
            this._isExecuting = false;
        }
    }

    protected abstract void OnExecute(CommandContext commandContext);
}

    这是一个抽象的命令类,这里只贴出了这个问题的主要的逻辑:需要在OnExecute方法执行之前设置_isExecuting的值为true,然后执行OnExecute方法,然后不管是否出现异常,都在执行完毕后,设置为false。子类实现这个类实现OnExecute方法来编写自己真正的执行代码。这时比较麻烦的一个问题是:在代码编写阶段,当子类的OnExecute方法内部出现异常时,Visual Studio都会直接把错误给定在这个类上,如下:

子类:

private class ConcreteCommand : Command
{
    protected override void OnExecute(CommandContext commandContext)
    {
        int i = 0;
        int j = 100 / i;
        //.......
    }
}

出现异常:

image

    调试的过程中,无法直接定位到子类,当代码很多时,找实现这个基类的子类是很烦人的事。而且找到了它以后,打上断点,还得重新运行一遍来运行同样的bug路径。时间就是这样浪费的,调试得很崩溃……


解决

    需要重构了基类的代码,但是由于Execute方法的设置_isExecuting字段的逻辑不能改变,所以并不简单。灵光一闪,有了以下的实现:

public abstract class Command
{
    public void Execute(CommandContext commandContext)
    {
        this._isExecuting = true;
        using (this.__isExecuting)
        {
            OnExecute(commandContext);
        }
    }
    protected abstract void OnExecute(CommandContext commandContext);

    private bool _isExecuting
    {
        get
        {
            return this.__isExecuting.Value;
        }
        set
        {
            this.__isExecuting.Value = value;
        }
    }
    private IsExecutingWrapper __isExecuting = new IsExecutingWrapper();

    /// <summary>
    /// 原来的模式增加了调试的困难度。
    /// 添加这个方法方便调试。
    /// </summary>
    private class IsExecutingWrapper : IDisposable
    {
        private bool _value;
        public bool Value
        {
            get
            {
                return this._value;
            }
            set
            {
                this._value = value;
            }
        }

        #region IDisposable Members

        public void Dispose()
        {
            this._value = false;
        }

        #endregion
    }
}

    成功解决:

image


后话

    因为我不只一次遇到过这个问题,所以我猜测肯定还会有朋友会遇到同样的问题。所以就把这个小问题冒昧的发在了首页。希望和大家分享。另外,如果你有更好的方法,可以用力的拍我。 :)

目录
相关文章
|
10月前
|
Java 程序员 测试技术
我有一个朋友写出了17种触发NPE的代码!避免这些坑
我有一个朋友,写代码的时候常常遭到NPE背刺,痛定思痛,总结了NPE出没的17个场景,哪一个你还没有遇到过?
每次生成代码注释后 然后把生成的代码插入原代码位置后 方法原来的注解就会错位
每次生成代码注释后 然后把生成的代码插入原代码位置后 方法原来的注解就会错位
46 1
|
10月前
|
安全 算法 C++
【C++ 异常 】深入了解C++ 异常机制中的 terminate()处理 避免不必要的错误(三)
【C++ 异常 】深入了解C++ 异常机制中的 terminate()处理 避免不必要的错误
201 0
|
10月前
|
存储 安全 NoSQL
【C++ 异常 】深入了解C++ 异常机制中的 terminate()处理 避免不必要的错误(二)
【C++ 异常 】深入了解C++ 异常机制中的 terminate()处理 避免不必要的错误
577 1
|
10月前
|
安全 程序员 编译器
【C++ 异常 】深入了解C++ 异常机制中的 terminate()处理 避免不必要的错误(一)
【C++ 异常 】深入了解C++ 异常机制中的 terminate()处理 避免不必要的错误
700 1
|
设计模式 消息中间件 JavaScript
干掉 “重复代码”,这三种方式绝了!
干掉 “重复代码”,这三种方式绝了!
36998 2
干掉 “重复代码”,这三种方式绝了!
|
Web App开发 存储
用9种办法解决 for 循环取 i
用9种办法解决 for 循环取 i
124 0
|
Java 数据库连接 数据库
这些让Spring事务失效的操作千万别犯!
在Spring框架中,事务是一种关键机制,用于确保数据库操作的一致性和完整性。然而,有时候事务可能会失效,导致意外的结果或数据不一致。下面是一些可能导致Spring事务失效的常见场景,以及相应的代码示例和解释。
这些让Spring事务失效的操作千万别犯!
|
Java 测试技术 API
开发小技巧系列 - 如何避免NPE,去掉if...else(四)
利用optional来处理各种IF-ELSE的判断
153 0
feof用法重点详解(易被误用判断文件结束!!!)
feof用法重点详解(易被误用判断文件结束!!!)