代码改变世界

Dispose模式释放非托管资源

2017-06-04 16:57  Dirichlet  阅读(304)  评论(0编辑  收藏  举报

实现方式用的是设计模式里的模板模式,基类先搭好框架,子类重写void Dispose(bool disposing) 即可。

需要注意的是基类的Finalize函数也就是析构函数调用的是虚函数void Dispose(bool disposing);而子类如果重写了这个虚函数,当析构子类对象时会调用到父类的析构函数,此时父类析构函数调用的是父类自己的Dispose(bool)版本还是子类重写了的Dispose(bool)版本?在C++中,是父类自己的Dispose(bool)版本。也就是虚函数在构造和析构函数中不起多态的作用。

.Net中呢?请思考。构造函数中调用虚函数可以做实验测试,析构函数不好测试。

// Design pattern for a base class.
public class Base: IDisposable
{
   //Implement IDisposable.
   public void Dispose() 
   {
      Dispose(true);
      GC.SuppressFinalize(this); 
   }

   protected virtual void Dispose(bool disposing) 
   {
      if (disposing) 
      {
         // Free other state (managed objects).
      }
      // Free your own state (unmanaged objects).
      // Set large fields to null.
   }

   // Use C# destructor syntax for finalization code.
   ~Base()
   {
      // Simply call Dispose(false).
      Dispose (false);
   }
}
// Design pattern for a derived class.
public class Derived: Base
{   
   protected override void Dispose(bool disposing) 
   {
      if (disposing) 
      {
         // Release managed resources.
      }
      // Release unmanaged resources.
      // Set large fields to null.
      // Call Dispose on your base class.
      base.Dispose(disposing);
   }
   // The derived class does not have a Finalize method
   // or a Dispose method without parameters because it inherits
   // them from the base class.
}

 

在c#中,析构函数的作用大大降低,可用于释放非托管资源。和c++有以下不同

1. 调用时机不同。c++中调用时机是固定的,但在c#中,垃圾回收器会在合适的时机调用析构函数。
2. c#没有virtual 析构函数,垃圾回收器会正确按次序调用子类和基类的析构函数。
3. c#中析构函数中的virtual机制仍然起作用(构造函数也是如此)。这将引起在子类尚未正确初始化或已经销毁的情况下基类仍通过虚函数访问子类。故避免在构造和析构函数中调用虚函数。
 
 

参考文章:

http://msdn.microsoft.com/zh-cn/library/b1yfkh5e(v=vs.80).aspx

http://msdn.microsoft.com/zh-cn/library/system.idisposable.dispose(v=VS.80).aspx

c#析构函数     http://blog.163.com/very_fyy/blog/static/22521685201156102354461/