我总是会搞混这些东西,还是写下来帮助记忆。

Finalize
即Object.Finalize(),C#中不允许使用Finalize,析构器就等价于Finalize。

Destructor
析构器(Destructor)是在对象没有被引用的时候,由CLR自动调用的。
任何包含非托管资源的类都必须定义析构器来释放这些资源,因为它们并不会在对象消亡时自动释放,而托管资源就可以。

Dispose方法
Dispose方法是IDisposable接口的实现方法,Dispose方法并不会被自动调用。

这里还有Dispose(bool)方法的概念,由于类的使用者或许会忘记使用Dispose()方法,并且析构器有可能二次执行析构操作,所以设计Dispose(bool)重载方法来判断并释放托管资源。合理的设计思想是,在Dispose()中使用Dispose(true)来显式释放托管资源和非托管资源,而在析构器中使用Dispose(false),只释放非托管资源(CLR会去自动调用托管资源的析构器)。在Dispose()方法中应使用GC.GC.SuppressFinalize()方法来阻止CLR调用析构器。

至于Close()方法,只是一种习惯名称,一般直接调用Dispose()方法。

来看MSDN里精辟的例子。

// Design pattern for the base class.
// By implementing IDisposable, you are announcing that instances
// of this type allocate scarce resources.
public class BaseResource: IDisposable
{
   // Pointer to an external unmanaged resource.
   private IntPtr handle;
   // Other managed resource this class uses.
   private Component Components;
   // Track whether Dispose has been called.
   private bool disposed = false;

// Constructor for the BaseResource object.
   public BaseResource()
   {
      // Insert appropriate constructor code here.
   }

// Implement IDisposable.
   // Do not make this method virtual.
   // A derived class should not be able to override this method.
   public void Dispose()
   {
      Dispose(true);
      // Take yourself off the Finalization queue 
      // to prevent finalization code for this object
      // from executing a second time.
      GC.SuppressFinalize(this);
   }

// Dispose(bool disposing) executes in two distinct scenarios.
   // If disposing equals true, the method has been called directly
   // or indirectly by a user's code. Managed and unmanaged resources
   // can be disposed.
   // If disposing equals false, the method has been called by the 
   // runtime from inside the finalizer and you should not reference 
   // other objects. Only unmanaged resources can be disposed.
   protected virtual void Dispose(bool disposing)
   {
      // Check to see if Dispose has already been called.
      if(!this.disposed)
      {
         // If disposing equals true, dispose all managed 
         // and unmanaged resources.
         if(disposing)
         {
            // Dispose managed resources.
            Components.Dispose();
         }
         // Release unmanaged resources. If disposing is false, 
         // only the following code is executed.
         CloseHandle(handle);
         handle = IntPtr.Zero;
         // Note that this is not thread safe.
         // Another thread could start disposing the object
         // after the managed resources are disposed,
         // but before the disposed flag is set to true.
         // If thread safety is necessary, it must be
         // implemented by the client.

}
      disposed = true;         
   }

// Use C# destructor syntax for finalization code.
   // This destructor will run only if the Dispose method 
   // does not get called.
   // It gives your base class the opportunity to finalize.
   // Do not provide destructors in types derived from this class.
   ~BaseResource()      
   {
      // Do not re-create Dispose clean-up code here.
      // Calling Dispose(false) is optimal in terms of
      // readability and maintainability.
      Dispose(false);
   }

// Allow your Dispose method to be called multiple times,
   // but throw an exception if the object has been disposed.
   // Whenever you do something with this class, 
   // check to see if it has been disposed.
   public void DoSomething()
   {
      if(this.disposed)
      {
         throw new ObjectDisposedException();
      }
   }
}

// Design pattern for a derived class.
// Note that this derived class inherently implements the 
// IDisposable interface because it is implemented in the base class.
public class MyResourceWrapper: BaseResource
{
   // A managed resource that you add in this derived class.
   private ManagedResource addedManaged;
   // A native unmanaged resource that you add in this derived class.
   private NativeResource addedNative;
   private bool disposed = false;

// Constructor for this object.
   public MyResourceWrapper()
   {
      // Insert appropriate constructor code here.
   }

protected override void Dispose(bool disposing)
   {
      if(!this.disposed)
      {
         try
         {
            if(disposing)
            {
               // Release the managed resources you added in
               // this derived class here.
               addedManaged.Dispose();         
            }
            // Release the native unmanaged resources you added
            // in this derived class here.
            CloseHandle(addedNative);
            this.disposed = true;
         }
         finally
         {
            // Call Dispose on your base class.
            base.Dispose(disposing);
         }
      }
   }
}

// This derived class does not have a Finalize method
// or a Dispose method without parameters because it inherits 
// them from the base class.


有一个热传的对象复活(resurrection)的例子

public class Resurrection
{
    public int Data;

public Resurrection(int data)
    {
        Data = data;
    }

~Resurrection()
    {
        Main.Instance = this;
    }
}

public class Main
{
    public static Resurrection Instance;

public static void Main()
    {
        Instance = new Resurrection(1);
        Instance = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();

// 看到了吗,在这里“复活”了。 
        Console.WriteLine(Instance.Data);
        Instance = null;
        GC.Collect();
        Console.ReadLine();
    }
}

还有一个弱引用的例子,弱引用的对象在回收以前还是可以被重复使用的。

public class Fat
{
    public int Data;

public Fat(int data)
    {
        Data = data;
    }
}

public class MainClass
{
    public static void Main()
    {
        Fat oFat = new Fat(1);
        WeakReference oFatRef = new WeakReference(oFat);

// 从这里开始,Fat对象可以被回收了。
        oFat = null;
        if (oFatRef.IsAlive)
        {
            Console.WriteLine(((Fat) oFatRef.Target).Data);
        }
        
        GC.Collect();
        Console.WriteLine(oFatRef.IsAlive); // False 
        Console.ReadLine();
    }
}


参考:
http://msdn2.microsoft.com/zh-cn/library/fs2xkftw(VS.80).aspx
http://blog.csdn.net/sykpboy/archive/2005/04/11/342971.aspx

转载于:https://www.cnblogs.com/forck/archive/2008/04/16/1156343.html

Finalize/Dispose/Destructor相关推荐

  1. Finalize,Dispose,SuppressFinalize

    MSDN建议按照下面的模式实现IDisposable接口: Code1 public class Foo: IDisposable2 {3 public void Dispose()4 {5 Disp ...

  2. dispose 模式 java_C#使用Dispose模式实现手动对资源的释放

    本文实例讲述了C#使用Dispose模式实现手动对资源的释放.分享给大家供大家参考.具体实现方法如下: //单一类的实现 class MyClass : IDisposable { public My ...

  3. C#垃圾回收学习总结

    浅谈C#垃圾回收 http://www.cnblogs.com/cuiyiming/archive/2013/03/26/2981931.html 理解C#垃圾回收机制我们首先说一下CLR(公共语言运 ...

  4. C++编程人员容易犯的10个C#错误

    C++编程人员容易犯的10个C#错误 C#的语法与C++非常相似,有些变化引起的错误却很严重,本讨论C++编程人员最容易犯的十个错误. 我们知道,C#的语法与C++非常相似,实现从C++向C#的转变, ...

  5. 面向对象——垃圾回收

     一.垃圾回收 托管堆的工作方式非常类似于栈,在某种程度上,对象子内存中一个挨一个地放置,这样很容易指向下一个空间存储单元的堆指针,来确定下一个对象的位置. 在垃圾回收器运行时,它会从堆中删除不再引用 ...

  6. java注释风格 与javadoc

    javadoc做注释  一. Java 文档 // 注释一行  /* ...... */ 注释若干行  /** ...... */ 注释若干行,并写入 javadoc 文档 通常这种注释的多行写法如下 ...

  7. 如何写Java文档注释(Java Doc Comments)

    本文翻译自How to Write Doc Comments for the Javadoc Tool,但是精简了一些私以为不重要的东西 本文不讨论如何使用javadoc工具自动生成文档的方法,而是主 ...

  8. java文档注释 编写格式

    java 文档注释 在sun主页上有java文档注释的编写格式 How to Write Doc Comments for the Javadoc Tool http://java.sun.com/j ...

  9. 【转】C#的内存管理:堆栈、托管堆与指针

    在32位的Windows操作系统中,每个进程都可以使用4GB的内存,这得益于虚拟寻址技术,在这4GB的内存中存储着可执行代码.代码加载的DLL和程序运行的所有变量,在C#中,虚拟内存中有个两个存储变量 ...

最新文章

  1. 大众点评字体_点评里的神笔马良!她的美食笔记会让你惊掉下巴!
  2. SAP系统中设备管理模块的主要增强出口
  3. pythonseleniumAPI
  4. 手把手实现YOLOv3(二)
  5. Java,JavaFX的流畅设计风格拨动开关
  6. Linux移植随笔:让内核支持nor flash
  7. Use Namesapce 使用方法简介
  8. Java collection 集合类架构
  9. 腾讯云服务器ftp部署及文件上传
  10. java判断是否为5的倍数,如何用编程实现“判断输入的正整数是否既是5又是7的正倍数,若是,则输出yes,否则输出no”?...
  11. win7添加java环境变量path_Win7怎么配置Java环境变量?
  12. HTML5 通过Vedio标签实现视频循环播放
  13. 【笔记本触摸屏】实用技巧整理
  14. vue实现非同源图片的下载功能--跨域问题(解决浏览器打开图片,而不是下载)
  15. mstar v56几路hdmi_MSTAR运用及问题汇总_整理
  16. 《途客圈创业记:不疯魔,不成活》一一2.5 完善拼图
  17. [单片机][FUSB302][PD1.0][PD2.0] PD协议 Demo 例子 代码
  18. Facebook或面临2000000000000美元罚款,扎克伯格认错
  19. 计算机可以查到刻录光盘的记录,光盘刻录信息记录在什么位置上
  20. windows的命令行(CMD)

热门文章

  1. php JSON数据格式化输出方法
  2. 在SQLserver数据库里设置作业的步骤
  3. SAP BADI应用
  4. ActiveMQ在C#中的应用
  5. OpenCV 【十八】图像平滑处理/腐蚀与膨胀(Eroding and Dilating)/开闭运算,形态梯度,顶帽,黑帽运算
  6. 三维重建【三】-------------------(三维重建资料收集)
  7. JDK源码分析 NIO实现
  8. Linux0.01内核根目录Makefile注释
  9. 超强的jquery极品插件--色彩选择器类/ 右键菜单类/ 图片新闻flash展示类
  10. gridview列 数字、货币和日期 显示格式