首先,对不起,如果这被认为是重复的 - 我知道这是一个常见的主题,但我看起来并没有找到满意的答案。
有很多问题询问 何时使用IDisposable
,但是从我读过的所有内容中,我只是看不出为什么你不会在每个课程中实现它你做。有什么可失去的?它是否有很大的性能影响?
我对IDisposable
的部分理解是,它所做的一件事是:
Dispose()ing other IDisposables owned by the object。请原谅我的无知,但这只适用于给定对象的字段/属性,还是也扩展到在其方法中创建的对象?
例如,如果在实现Font
的类中的方法内创建了IDisposable
,但Font
未使用using
块进行初始化,或者.Dispose()
d明确地在方法的最后;当它的IDisposable
父母/班级被GCd /处置时会被处置吗?或者,Font
永远不会被处置?
我不是故意离题,但如果确实这样做会像这样“抓住所有人”(有效地处理任何错误的子IDisposable
对象,否则这些对象将被置于其他地方)这个理由足以证明总是尽可能地实施IDisposable
?
答案 0 :(得分:9)
规则非常简单,如果您的类中有任何一次性类型的字段,则需要实现IDisposable。这样你就可以处理它们了。
方法内部发生的事情与您班级的字段几乎没有关系。如果您创建字体并将其存储在字段中然后是,则上述规则表明您需要Dispose()方法。如果您不是像通常那样使用字体来绘制某些内容,那么请始终使用 using 语句,以便在使用完字体后立即处理该字体。
答案 1 :(得分:1)
大多数对象不需要它。该框架很好地照顾Garbage Collection
。 COM
个对象和Graphics
个对象属于并且应该实现IDisposable
以进行良好清理。是的,回收物体时可能会有一些固有的性能损失。
答案 2 :(得分:0)
一个对象应该实现IDisposable
,如果它知道需要在宇宙结束之前的某个时间发生的事情,那么没有其他事情可以获得确保这些事情完成所需的知识和动力; Dispose
方法让对象知道它最好立即做这些事情,因为否则它们可能永远不会完成。
抽象类型或接口应该实现IDisposable
,如果派生或实现该类型的实例可能知道需要在Universe结束之前发生的事情,和持有引用的最后一个实体很容易知道它是从抽象或接口类型派生或实现的东西的实例,而不是实现实现IDisposable
的更具体类型的东西。
实现IDisposable
的实现IDisposable
的接口实现IDisposable
的类型,无论是否有其他理由这样做。
有理由实施IDisposable
的类型应该这样做。不应该的类型,不应该。
<强>附录强>
要理解为什么不应该总是实现Dispose
,考虑这样做的实际成本可能会有所帮助。处理器调用无操作{{1}}方法所需的时间是微不足道的,但这不是真正的考虑因素。当人们认为大多数对象符合以下四种描述中的一种时,就会出现更大的问题:
封装资源的对象,需要有一个明确定义的所有者
包含可变状态的对象,需要有一个明确定义的所有者。
不可变类型的对象,不需要有明确定义的所有者。
可变类型的实例,它们永远不会暴露给可能会改变它们的代码,并且不需要有明确定义的所有者。
正确使用可变对象通常需要跟踪谁拥有它们,就像持有资源的对象一样。同样,如果使用具有可变状态的对象来封装另一个对象的可变状态,则正确使用后一个对象将需要跟踪谁拥有它,就像封装其他拥有资源的对象的对象一样。区别在于具有资源的对象和具有可变状态的对象之间的区别在于,当使用可变类型的实例来封装不可变对象的状态时(确保实例永远不会暴露给会使其变异的代码),它将不再存在有必要跟踪谁拥有它。相比之下,有必要跟踪封装其他持有资源的对象的对象的所有权,即使这些对象在语义上是不可变的。