3

首先,很抱歉,如果这被认为是重复的 - 我知道这是一个常见的话题,但我已经看过并没有找到令人满意的答案。

有很多问题询问何时使用IDisposable但从我读过的所有内容来看,我只是不明白为什么你不会在你制作的每个类中实现它。有什么可失去的?它对性能有很大影响吗?

我的部分理解IDisposable是它所做的事情之一是: Dispose() 处理对象拥有的其他 IDisposables。原谅我的无知,但这仅适用于给定对象的字段/属性,还是也扩展到在其方法中创建的对象?

例如,如果 aFont是在实现 的类中的方法内创建的IDisposable,但Font没有用using块初始化,或者.Dispose()d 在方法末尾显式初始化;当它的IDisposable父/类被 GCd/disposed 时它会被处理吗?否则,Font永远不会被处置?

我并不是要跑题,但如果它确实会像这样“包罗万象”(有效地处理任何IDisposable本来不会被处理的错误子对象),那么仅凭这个理由还不足以证明其合理性吗?总是IDisposable尽可能地实施?

4

3 回答 3

9

The rule is very simple, you need to implement IDisposable if you have any fields in your class that are of a type that is disposable. So that you can dispose them.

What happens inside a method has little to do with the fields of your class. If you create the font and store it in a field then yes, the above rule says that you need a Dispose() method. If you don't but just use the font to draw something, like you normally do, then always use the using statement so you immediately dispose the font after you are done using it.

于 2013-09-06T00:19:05.267 回答
1

大多数对象不需要它。该框架很好地照顾Garbage Collection. COMobjects 和Graphicsobjects 是那些可以进行并且应该实现IDisposable良好清理的对象。是的,回收对象时可能会有一些固有的性能损失。

于 2013-09-06T00:09:16.853 回答
0

如果一个对象IDisposable知道在宇宙终结之前的某个时间需要发生的事情,那么它就应该实现,并且没有其他任何东西具有确保这些事情完成所必需的知识和动力;该Dispose方法让对象知道它最好立即执行这些操作,否则它们可能永远不会完成。

IDisposable如果派生或实现该类型的实例可能知道在宇宙结束之前的某个时间需要发生的事情,并且最后一个持有引用的实体很容易知道它是一个抽象类型或接口,那么抽象类型或接口应该实现从抽象或接口类型派生或实现的事物的实例,而不是实现更具体的类型的事物IDisposable

实现继承接口的类型IDisposable将被要求实现IDisposable,无论它是否有任何其他理由这样做。

有理由实现的类型IDisposable应该这样做。不应该的类型,不应该。

附录

要了解为什么不应该总是实施IDisposable,考虑这样做的实际成本可能会有所帮助。处理器调用无操作方法所需的时间Dispose是微不足道的,但这不是真正的考虑因素。当人们认为大多数对象符合以下四种描述之一时,就会出现更大的问题:

  • 封装资源的对象,需要有一个明确定义的所有者

  • 封装可变状态的对象,需要有一个明确定义的所有者。

  • 不可变类型的对象,不需要明确定义的所有者。

  • 永远不会暴露于可能改变它们的代码的可变类型的实例,并且不需要具有明确定义的所有者。

正确使用可变对象通常需要跟踪谁拥有它们,就像拥有资源的对象一样。同样,如果使用具有可变状态的对象来封装另一个对象的可变状态,则正确使用后一个对象将需要跟踪谁拥有它,就像对象封装拥有资源的其他对象一样。具有资源的对象和具有可变状态的对象之间的区别在于,当使用可变类型的实例来封装不可变对象的状态时(确保实例永远不会暴露给会对其进行变异的代码),它将不再有必要跟踪谁拥有它。相比之下,有必要跟踪封装了其他持有资源的对象的对象的所有权,即使这些对象在语义上是不可变的。

于 2013-09-07T21:25:31.077 回答