我何时在类上实现IDispose而不是析构函数?我读过这篇文章,但我仍然忽略了这一点.
我的假设是,如果我在一个对象上实现IDispose,我可以显式"破坏"它,而不是等待垃圾收集器这样做.它是否正确?
这是否意味着我应该总是在对象上显式调用Dispose?这有什么常见的例子?
终结器(也称为析构函数)是垃圾收集(GC)的一部分 - 当发生这种情况时(或者即使发生这种情况)它是不确定的,因为GC主要是由于内存压力(即需要更多空间)而发生的.终结器通常仅用于清理非托管资源,因为托管资源将有自己的收集/处置.
因此IDisposable
用于确定性地清理对象,即现在.它不收集对象的内存(仍属于GC) - 但用于关闭文件,数据库连接等.
以前有很多主题:
确定性的最终确定
处理对象
使用块
资源
最后,请注意,IDisposable
对象也有一个终结器并不罕见; 在这种情况下,Dispose()
通常是调用GC.SuppressFinalize(this)
,这意味着GC不会运行终结器 - 它只是抛弃内存(便宜得多).如果忘记Dispose()
对象,终结器仍会运行.
该Finalize()
方法的作用是确保.NET对象可以在收集垃圾时清理非托管资源.但是,应尽快释放数据库连接或文件处理程序等对象,而不是依赖于垃圾回收.为此,您应该实现IDisposable
接口,并在Dispose()
方法中释放您的资源.
MSDN上有一个非常好的描述:
此接口的主要用途是释放非托管资源.垃圾收集器当不再使用该对象时,自动释放分配给托管对象的内存.但是,无法预测垃圾收集何时发生.此外,垃圾收集器不了解非托管资源, 例如窗口句柄,或打开文件和流.
使用此接口的Dispose方法 与垃圾收集器一起显式释放非托管资源.当不再需要该对象时,对象的 使用者可以调用此方法.
在C#析构函数中唯一应该是这一行:
Dispose(False);
而已.在该方法中不应该有任何其他东西.