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

查看:15
本文介绍了使用 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#中,我经常想做的事

In C#, I often want to do

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 在技术上 is 意味着用于具有非托管资源的事物,但是 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天全站免登陆