Dispose模式

Dispose模式释放非托管资源。

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

Notes:

需要注意的是基类的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/

时间: 2024-08-25 10:28:27

Dispose模式的相关文章

第七节:使用实现了dispose模式的类型

知道类型如何实现dispose模式之后,接下来看一下开发人员怎样使用提供了dispose模式的类型.这里不再讨论前面的SafeHandle类,而是讨论更常用的FileStream类. 可以利用FileStream打开一个文件,从文件中读取字节,向文件中写入字节,并关闭文件.一个FileStream对象在构造时,它会调用Win32 CreateFile函数,函数返回的句柄保存在SafeFileHandle中,然后通过FileStream对象的一个私有字段来维护运载该对象的引用,FileStream

[转]改善C#程序的建议4:C#中标准Dispose模式的实现

需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不受CLR管理的对象,windows内核对象,如文件.数据库连接.套接字.COM对象等: 毫无例外地,如果我们的类型使用到了非托管资源,或者需要显式释放的托管资源,那么,就需要让类型继承接口IDisposable.这相当于是告诉调用者,该类型是需要显式释放资源的,你需要调用我的Dispose方法. 不

C#中标准Dispose模式的实现

本文引自:http://www.cnblogs.com/luminji/archive/2011/03/29/1997812.html 需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不受CLR管理的对象,windows内核对象,如文件.数据库连接.套接字.COM对象等: 毫无例外地,如果我们的类型使用到了非托管资源,或者需要显式释放的托管资源,那

改善C#程序的建议4:C#中标准Dispose模式的实现

原文:改善C#程序的建议4:C#中标准Dispose模式的实现 需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不受CLR管理的对象,windows内核对象,如文件.数据库连接.套接字.COM对象等: 毫无例外地,如果我们的类型使用到了非托管资源,或者需要显式释放的托管资源,那么,就需要让类型继承接口IDisposable.这相当于是告诉调用者,该

C#中标准Dispose模式的实现(转载)

需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不受CLR管理的对象,windows内核对象,如文件.数据库连接.套接字.COM对象等: 毫无例外地,如果我们的类型使用到了非托管资源,或者需要显式释放的托管资源,那么,就需要让类型继承接口IDisposable.这相当于是告诉调用者,该类型是需要显式释放资源的,你需要调用我的Dispose方法. 不

编写高质量代码改善C#程序的157个建议——建议49:在Dispose模式中应提取一个受保护的虚方法

建议49:在Dispose模式中应提取一个受保护的虚方法 在标准的Dispose模式中,真正的IDisposable接口的Dispose方法并没有做实际的清理工作,它其实是调用了下面的这个带bool参数且受保护的的虚方法: /// <summary> /// 非密封类修饰用protected virtual /// 密封类修饰用private /// </summary> /// <param name="disposing"></param&

编写高质量代码改善C#程序的157个建议——建议50:在Dispose模式中应区别对待托管资源和非托管资源

建议50:在Dispose模式中应区别对待托管资源和非托管资源 真正资源释放代码的那个虚方法是带一个bool参数的,带这个参数,是因为我们在资源释放时要区别对待托管资源和非托管资源. 提供给调用者调用的显式释放资源的无参Dispose方法中,调用参数是true: public void Dispose() { //必须为true Dispose(true); //省略其他代码 } 这表明,这时候代码要同时处理托管资源和非托管资源. 在供垃圾回收器调用的隐式清理资源的终结器中,调用的是false:

C# Dispose模式

需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不受CLR管理的对象,windows内核对象,如文件.数据库连接.套接字.COM对象等: 毫无例外地,如果我们的类型使用到了非托管资源,或者需要显式释放的托管资源,那么,就需要让类型继承接口IDisposable.这相当于是告诉调用者,该类型是需要显式释放资源的,你需要调用我的Dispose方法. 不

.NET Dispose模式的实现

/// <summary> /// Dispose Pattern /// </summary> /// <remarks> /// 由逻辑可知: /// 1.不管是手动调用Dispose方法还是系统自动调用析构函数,均会执行[非托管资源]释放程序 /// 2.系统自动调用析构函数时,不会执行[托管资源]释放程序 /// </remarks> public class DisposableObject : IDisposable { /// <summ