使用 IDisposable 和“使用"是否滥用?作为获得“范围行为"的手段;为了异常安全? [英] Is it abusive to use IDisposable and "using" as a means for getting "scoped behavior" for exception safety?

查看:13
本文介绍了使用 IDisposable 和“使用"是否滥用?作为获得“范围行为"的手段;为了异常安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 C++ 中经常使用的东西是让类 A 通过 A 处理另一个类 B 的状态进入和退出条件> 构造函数和析构函数,以确保如果该范围内的某些内容抛出异常,则 B 在退出该范围时将具有已知状态.就首字母缩略词而言,这不是纯粹的 RAII,但它仍然是一种既定的模式.

Something I often used back in C++ was letting a class A handle a state entry and exit condition for another class B, via the A constructor and destructor, to make sure that if something in that scope threw an exception, then B would have a known state when the scope was exited. This isn't pure RAII as far as the acronym goes, but it's an established pattern nevertheless.

在C#中,我经常想做

class FrobbleManager
{
    ...

    private void FiddleTheFrobble()
    {
        this.Frobble.Unlock();
        Foo();                  // Can throw
        this.Frobble.Fiddle();  // Can throw
        Bar();                  // Can throw
        this.Frobble.Lock();
    }
}

需要这样做

private void FiddleTheFrobble()
{
    this.Frobble.Unlock();

    try
    {            
        Foo();                  // Can throw
        this.Frobble.Fiddle();  // Can throw
        Bar();                  // Can throw
    }
    finally
    {
        this.Frobble.Lock();
    }
}

如果我想在 FiddleTheFrobble 返回时保证 Frobble 状态.代码会更好

if I want to guarantee the Frobble state when FiddleTheFrobble returns. The code would be nicer with

private void FiddleTheFrobble()
{
    using (var janitor = new FrobbleJanitor(this.Frobble))
    {            
        Foo();                  // Can throw
        this.Frobble.Fiddle();  // Can throw
        Bar();                  // Can throw
    }
}

其中 FrobbleJanitor 看起来大致

class FrobbleJanitor : IDisposable
{
    private Frobble frobble;

    public FrobbleJanitor(Frobble frobble)
    {
        this.frobble = frobble;
        this.frobble.Unlock();
    }

    public void Dispose()
    {
        this.frobble.Lock();
    }
}

这就是我想做的.现在现实迎头赶上,因为我想要使用要求 FrobbleJanitor with using.我可以将其视为代码审查问题,但有些事情困扰着我.

And that's how I want to do it. Now reality catches up, since what I want to use requires that the FrobbleJanitor is used with using. I could consider this a code review issue, but something is nagging me.

问题:以上是否会被视为对usingIDisposable 的滥用?

Question: Would the above be considered as abusive use of using and IDisposable?

推荐答案

我不这么认为,这是必然的.IDisposable 在技术上意味着用于具有非托管资源的事物,但是 using 指令只是实现 try .. finally { dispose }<的常见模式的一种巧妙方式/代码>.

I don't think so, necessarily. IDisposable technically is meant to be used for things that have non-managed resources, but then the using directive is just a neat way of implementing a common pattern of try .. finally { dispose }.

纯粹主义者会争辩说是的 - 这是滥用",而在纯粹主义者的意义上确实如此;但我们大多数人不是从纯粹主义的角度编码,而是从半艺术的角度编码.在我看来,以这种方式使用使用"结构确实非常艺术.

A purist would argue 'yes - it's abusive', and in the purist sense it is; but most of us do not code from a purist perspective, but from a semi-artistic one. Using the 'using' construct in this way is quite artistic indeed, in my opinion.

您可能应该在 IDisposable 之上添加另一个接口以将其推得更远,向其他开发人员解释为什么该接口隐含 IDisposable.

You should probably stick another interface on top of IDisposable to push it a bit further away, explaining to other developers why that interface implies IDisposable.

这样做还有很多其他的选择,但最终,我想不出任何像这样简洁的方法,所以去吧!

There are lots of other alternatives to doing this but, ultimately, I can't think of any that will be as neat as this, so go for it!

这篇关于使用 IDisposable 和“使用"是否滥用?作为获得“范围行为"的手段;为了异常安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆