C#中的析构函数,GC和IDisposable的用法

析构函数

    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();
            }
        }
Component的析构函数

 

 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
    }
原文地址:https://www.cnblogs.com/noigel/p/12468724.html