【发布时间】:2023-03-29 22:57:01
【问题描述】:
接口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 构造可以为thon 执行此操作。
IDisposable 的这种用法与 as stated in the documentation 的预期用途不一致,但诱惑仍然存在。
是否有具体的理由来说明这是一个坏主意并永远打消我的幻想,例如垃圾收集的复杂性、异常处理等。或者我应该继续以这种方式滥用这种语言概念来放纵自己吗?
【问题讨论】:
-
还有很多其他的概念可能会被误用,上面就是其中之一,唯一的就是可读性,记住你的代码应该是清晰的/可读的并且可以被其他人维护开发人员。
-
我同意哈比卜。永远想一想从现在起 18 个月后将不得不使用您的代码的可怜的混蛋。那个混蛋很有可能就是你:-)
-
这是一个主观问题,但您可以注意到 ASP.NET MVC 框架以这种方式滥用 IDisposable - 例如
FormExtensions.BeginForm -
我已经编辑了这个问题,更清楚地表明我不是在寻找意见(我已经有一个:“这很好用!”),但出于具体原因,这种用法可能/将导致问题。
标签: c# .net idisposable