c# - 取 2 : Is it abusive to use IDisposable and “using” as a means for getting “scoped behavior” ?

标签 c# exception anti-patterns

TL;DR -- 在 IDisposable.Dispose 中执行业务逻辑是否合适?

在寻找答案时,我通读了这个问题:Is it abusive to use IDisposable and "using" as a means for getting "scoped behavior" for exception safety?它非常接近解决这个问题,但我想全力攻击它。我最近遇到了一些看起来像这样的代码:

class Foo : IDisposable
{
    public void Dispose()
    {
        ExecuteSomeBusinessBehavior();
        NormalCleanup();
    }
}

并在以下上下文中使用:

try 
{
    using (var myFoo = new Foo())
    {
        DoStuff();
        foo.DoSomethingFooey();
        ...
        DoSomethingElse();
        Etc();
    }
}
catch (Exception ex)
{
    // Handle stuff
}

一看到这段代码,我就开始手痒了。这是我在查看这段代码时看到的内容:

首先,只看使用上下文,当代码离开使用范围时,实际的业务逻辑(不仅仅是清理代码)将被执行并不明显。

其次,如果“using”范围内的任何代码抛出异常,Dispose 方法中的业务逻辑仍将执行,并在 Try/Catch 可以处理异常之前执行。

我向 StackOverflow 社区提出的问题是:将业务逻辑放在 IDisposable.Dispose 方法中是否有意义?有没有一种模式可以实现类似的结果而不让我感到痒痒?

最佳答案

(对不起,这更像是评论,但它超过了评论长度限制。)

实际上,在 .NET 框架中有一个示例,其中 IDisposable 用于创建范围并在处理时做有用的工作:TransactionScope

引自TransactionScope.Dispose :

Calling this method marks the end of the transaction scope. If the TransactionScope object created the transaction and Complete was called on the scope, the TransactionScope object attempts to commit the transaction when this method is called.

如果你决定走那条路,我会建议

  • 您明显地表明您的对象创建了一个作用域,例如,通过调用它 FooScope 而不是 Foo

  • 当异常导致代码离开您的范围时,您会认真思考应该发生什么。在 TransactionScope 中,在 block 末尾调用 Complete 的模式确保 Dispose 可以区分这两种情况。

关于c# - 取 2 : Is it abusive to use IDisposable and “using” as a means for getting “scoped behavior” ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17321300/

相关文章:

c# - WebAPI 多个冲突路由 - 基于身份验证

c# - 在 c# 的 gridview 编辑模式下填充下拉列表的问题

c# - "using"构造和异常处理

java - 当对象需要在 try/catch block 中时,IDE 的 "know"如何处理?

exception - .NET 2.0 与 .NET 4.0 加载错误

ruby - 为什么是 "wrong to require rubygems"?

javascript - JavaScript 存在哪些反模式?

c# - 从两个不同的输入上传两个不同的文件

c# - 如何使用 WPF 后台 worker

design-patterns - 通用模型是反模式吗?