接口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不一致,但诱惑仍然存在。
是否有具体的理由来说明这是一个坏主意并永远消除我的幻想,例如垃圾收集,异常处理等的并发症。或者我应该继续以这种方式滥用这种语言概念来放纵自己?
答案 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
事实上,我非常确定微软自己会在某些库中使用它。我的经验法则是 - 如果它提高了可读性,那就去吧。