析构函数
public class Demo { ~Demo() { MessageBox.Show("Demo Destructed"); } }
调用时机
GC在合适的对没有引用的对象调用其析构函数。
举例
在一个简单的Form中,创建一个Demo对象
public Form1() { InitializeComponent(); Demo d = new Demo(); }
当窗口关闭时,GC就会回收Demo d的对象,
protected override void Finalize() { try { this.Dispose(false); } finally { base.Finalize(); } }
GC
手动调用
private void button1_Click(object sender, EventArgs e) { Demo d = new Demo(); d = null; }
点击按钮,虽然对象不再被引用,但是暂时没有被回收,
加上
private void button1_Click(object sender, EventArgs e) { Demo d = new Demo(); d = null; GC.Collect(); }
点击按钮,就会执行垃圾回收,调用Demo d的析构函数。
使用
GC.SuppressFinalize(d);
就会阻止对象d执行析构方法。
IDisposable的使用
最简单使用
public class Demo:IDisposable { public void Dispose() { MessageBox.Show("Handle Unmanaged Resources"); } }
然后在必要的地方显式的调用Dispose方法,来释放未托管资源。
if(d!=null) d.Dispose();
如何让Dispose自动调用
using(Demo d=new Demo()) { //do your work here }
最好的机制
既能手动释放,又可以让析构函数自动调用,同时让其只调用一次
public class Demo:IDisposable { private bool isDisposed = false; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if(!isDisposed) { if(disposing) { //手动调用相关托管对象的Dispose方法 } // 清理其他 MessageBox.Show("Handle Unmanaged Resouces"); } isDisposed = true; } ~Demo() { Dispose(false); } //其他成员函数内部需要先判断下isDisposed }