滥用IDisposable是否受益于“使用”被认为有害的陈述?

时间:2015-04-14 13:17:03

标签: c# .net idisposable

接口IDisposable的目的是以有序的方式释放非托管资源。它与using关键字一起使用,该关键字在有问题的资源被处理之后定义范围。

因为这种机智是如此简洁,所以我一直试图让类实现IDisposable以便能够以不适合的方式滥用这种机制。例如,可以实现类来处理嵌套的上下文,如下所示:

class Context : IDisposable
{
    // Put a new context onto the stack
    public static void PushContext() { ... }

    // Remove the topmost context from the stack
    private static void PopContext() { ... }

    // Retrieve the topmost context
    public static Context CurrentContext { get { ... } }

    // Disposing of a context pops it from the stack
    public void Dispose()
    {
        PopContext();
    }
}

调用代码的用法可能如下所示:

using (Context.PushContext())
{
   DoContextualStuff(Context.CurrentContext);
} // <-- the context is popped upon leaving the block

(请注意,这只是一个例子而不是这个问题的主题。)

在离开Dispose()语句的范围时调用using的事实也可以被利用来实现依赖于范围的各种事物,例如计时器。这也可以通过使用try ... finally构造来处理,但在这种情况下,程序员必须手动调用某个方法(例如Context.Pop),using构造可以为此做。

IDisposable的这种用法与其预期目的as stated in the documentation不一致,但诱惑仍然存在。

是否有具体的理由来说明这是一个坏主意并永远消除我的幻想,例如垃圾收集,异常处理等的并发症。或者我应该继续以这种方式滥用这种语言概念来放纵自己?

3 个答案:

答案 0 :(得分:10)

因此在asp.net MVC视图中,我们看到以下构造:

using(Html.BeginForm())
{
    //some form elements
}

滥用?微软说不(间接)。

如果你有一个 需要 的构造,一旦你完成它,IDisposable通常可以很好地解决。我不止一次这样做过。

答案 1 :(得分:3)

“滥用IDisposable界面以这种方式使用它”?可能。

使用using作为纯粹的“范围”构造是否可以实现更明显的意图和更好的代码可读性?肯定。

后者胜过我,所以我说要用它。

答案 2 :(得分:0)

你肯定不会成为第一个滥用&#39;这样就可以了。可能我最喜欢使用它的是定时器,正如StatsD.NET client所示:

using StatsdClient;
...
using (statsd.LogTiming( "site.db.fetchReport" ))
{
  // do some work
}
// At this point your latency has been sent to the server

事实上,我非常确定微软自己会在某些库中使用它。我的经验法则是 - 如果它提高了可读性,那就去吧。