为什么我必须从IDisposable实现Dispose,为什么不只是一个简单的方法来释放...?

时间:2013-03-24 23:57:21

标签: c# .net idisposable

为什么我必须从IDisposable实现Dispose,如果我只在我的类中实现释放非托管资源的任何方法怎么办?

我说话的人假装知道告诉我必须这样做的原因。

老实说,我认为这是一个非常明显的问题 - 虽然在一些开发者之间我不知道但

3 个答案:

答案 0 :(得分:13)

  

我说话的人假装知道原因只是告诉我我也有。

因为它建立了释放本机资源的通用接口(方法)。当您正确实施IDisposable时,我现在可以:

  1. 如果需要,可以通过IDisposable界面使用您的类型。
  2. using语句中包含您的类型创建,而不是在整个地方写try/finally
  3. 使用自动化工具检测我未能在您的类实例上调用Dispose()的实例(即实现IDisposable的类的实例)。
  4. 依靠运行时来调用你的终结器(只要你正确地实现你的类就会调用Dispose())如果我犯了不直接调用Dispose()的错误。不是说你应该这样做,因为它使资源管理不确定,但它是一个很好的以防万一功能。
  5. 不必实施IDisposable,您应该在您的类型管理本机资源(运营时无法管理的资源)时使用。

答案 1 :(得分:2)

IDisposable界面的独特之处在于它的存在实际上对一个类的描述少于它的缺席。如果一个类实现了IDisposable,那么该类表明可能已经要求某个外部实体(可能是宇宙中任何地方的任何类型的实体)代表它做某事直到进一步注意,可能对其他潜在用户造成损害,因此可能有责任确保外部实体在不再需要其服务时得到通知。例如,封装输入流的对象可能已经要求底层操作系统独占访问文件[可能在另一台计算机上];直到对象告诉操作系统它已完成文件,或托管对象的应用程序终止,宇宙中任何其他地方的任何人都无法访问该文件。因此,对象有责任在不再需要文件时通知OS。请注意,输入流的使用者并不真正关心流是否实际上已要求任何外部实体代表其执行任何操作。相反,只要流的消费者知道它不再需要它,消费者就会在流上调用Dispose,然后可以执行任何操作,,如果有的话,,必须确保所有仍代表其行事的实体(如果有的话)被通知他们可以停止这样做。

请注意IDisposable并未表示某个类实际上会要求任何外部实体代表它做任何事情,也不会说它实际上有任何清理责任,也不会说任何实际的伤害都会因放弃而造成没有调用Dispose的实例。但是,如果某个类实现IDisposable,则会提供一个非常强烈的指示,即该类的实例承担任何责任以确保外部资源得到清理起来。至少,它提供了一个强有力的指示,即可以安全地放弃对象,而不会遗漏任何必要的清理操作[某些类型如WeakReference需要清理但不实施IDisposable,而是依赖于最终确定]

因此,我认为类的一个很好的理由是实现IDisposable而不是使用其他一些清理方法,以避免给出错误的印象,即不需要进行清理。

答案 2 :(得分:0)

如果您可以确保在任何情况下都会调用您的发布功能,无论发生什么,异常,应用程序崩溃等等,我会说,您不必实现IDisposable接口。

但事实是,如果您正在编写课程或组件,则无法预测客户将如何使用它。他们可能会忘记调用你的发布功能。这将导致您的资源无法释放。

实施IDisposable接口是一种很好的做法