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

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

因为这个meachnism是如此简洁,我一直试图让类实现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 

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

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

IDisposable这种用法与文档中所述的预期目的不一致,但诱惑仍然存在。

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

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

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

虐待? 微软说不(间接)。

如果你有一个构造,一旦你完成它需要一些事情发生, IDisposable通常可以非常好地工作。 我不止一次这样做过。

“以这种方式使用它是滥用IDisposable接口吗?” 大概。

使用using作为纯粹的“范围”构造是否会产生更明显的意图和更好的代码可读性? 当然。

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

你肯定不会是第一个以这种方式“滥用”IDisposable的人。 可能我最喜欢使用它的是定时器,因为StatsD.NET客户端演示:

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

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