C#调用析构方法详解

开发 后端
这里介绍在释放托管资源之前要先C#调用析构方法,然后第二次才真正释放托管资源,这样一来,两次删除动作的花销比一次大多的!

在向大家详细介绍C#调用析构方法之前,首先让大家了解下C#中定义析构方法,然后全面介绍C#调用析构方法。

在C#中定义析构方法的格式是" ~CLASS_NAME() ".非常需要注意的是,如果一个类中没有使用到非托管资源,那么请一定不要定义析构方法,这是因为对象执行了析构方法,那么"垃圾回收器"在释放托管资源之前要先C#调用析构方法,然后第二次才真正释放托管资源,这样一来,两次删除动作的花销比一次大多的! (不过,即使你在类中已经定义了析构方法,仍然有办法"屏蔽"它,这将在后面的代码范例中说明) 在析构方法中,就是用户自己写的释放非托管资源的代码段.

下面使用一段代码来示范Dispose()方法和析构方法如何使用:

  1. public class ResourceHolder : System.IDisposable  
  2. {  
  3. public void Dispose()  
  4. {  
  5. Dispose(true);  
  6.  
  7. System.GC.SuppressFinalize(this);  
  8. // 上面一行代码作用是防止"垃圾回收器"调用这个类中的方法  
  9. // " ~ResourceHolder() "  
  10. // 为什么要防止呢? 因为如果用户记得调用Dispose()方法,那么  
  11. // "垃圾回收器"就没有必要"多此一举"地再去释放一遍"非托管资源"了  
  12. // 如果用户不记得调用呢,就让"垃圾回收器"帮我们去"多此一举"吧 ^_^  
  13. // 你看不懂我上面说的不要紧,下面我还有更详细的解释呢!  
  14. }  
  15.  
  16. protected virtual void Dispose(bool disposing)  
  17. {  
  18. if (disposing)  
  19. {  
  20. // 这里是清理"托管资源"的用户代码段  
  21. }  
  22. // 这里是清理"非托管资源"的用户代码段  
  23. }  
  24.  
  25. ~ResourceHolder()  
  26. {  
  27. Dispose(false);  
  28. }  

这里,我们必须要清楚,需要用户调用的是方法Dispose()而不是方法Dispose(bool),然而,这里真正执行释放工作的方法却并不是Dispose(),而是Dispose(bool) ! 为什么呢?仔细看代码,在Dispose()中,调用了Dispose(true),而参数为"true"时,作用是清理所有的托管资源和非托管资源;大家一定还记得我前面才说过,"使用析构方法是用来释放非托管资源的",那么这里既然Dispose()可以完成释放非托管资源的工作,还要析构方法干什么呢? 其实,析构方法的作用仅仅是一个"备份"!

严格地说,凡执行了接口"IDisposable"的类,那么只要程序员在代码中使用了这个类的对象实例,那么早晚得调用这个类的Dispose()方法,同时,如果类中含有对非托管资源的使用,那么也必须释放非托管资源! 可惜,如果释放非托管资源的代码放在析构方法中(上面的例子对应的是 " ~ResourceHolder() "),那么程序员想调用这段释放代码是不可能做到的(因为析构方法不能被用户调用,只能被系统,确切说是"垃圾回收器"调用),所以大家应该知道为什么上面例子中"清理非托管资源的用户代码段"是在Dispose(bool)中,而不是~ResourceHolder()中! 不过不幸的是,并不是所有的程序员都时刻小心地记得调用Dispose()方法,万一程序员忘记调用此方法,托管资源当然没问题,早晚会有"垃圾回收器"来回收(只不过会推迟一会儿),那么非托管资源呢?它可不受CLR的控制啊!难道它所占用的非托管资源就永远不能释放了吗? 当然不是!我们还有"析构方法"呢! 如果忘记调用Dispose(),那么"垃圾回收器"也会C#调用析构方法来释放非托管资源的!(多说一句废话,如果程序员记得调用Dispose()的话,那么代码"System.GC.SuppressFinalize(this);"则可以防止"垃圾回收器"C#调用析构方法,这样就不必多释放一次"非托管资源"了) 所以我们就不怕程序员忘记调用Dispose()方法了.

所以我说了这么一大堆的理由,综合起来只有两点:
◆程序员们啊,千万不要忘记调用Dispose()方法! (如果有的话o(∩_∩)o...哈哈)
◆万一忘记,不要着急...还有救!!! 因为还有"垃圾回收器"帮我们自动C#调用析构方法!

【编辑推荐】

  1. C#文法产生式概述
  2. C#类型声明简单分析
  3. C#命名空间和程序集学习笔记
  4. 利用C#清空回收站学习经验
  5. C# Color枚举简单描述
责任编辑:佚名 来源: 博客园
相关推荐

2009-08-14 17:24:28

C#构造函数和析构函数

2009-07-30 15:24:13

C#析构函数C#构造函数

2009-09-03 13:14:55

C#构造函数C#析构函数

2009-09-03 17:10:57

2009-08-31 18:05:14

C#调用WalkTre

2009-08-31 16:33:28

C#调用Dispose

2009-08-05 14:54:09

VB调用C#类库

2009-08-03 13:13:52

C#调用Outlook

2009-08-21 13:18:25

C#异步调用

2009-09-01 11:04:59

C#调用扩展方法

2009-09-03 14:20:21

C#日期格式化

2009-08-03 12:57:27

C#调用DLL

2010-02-04 16:39:26

C++析构函数

2010-01-18 15:53:27

C++析构函数

2009-09-02 13:15:23

C#数组复制

2009-08-20 13:47:57

C#验证输入方法

2009-08-12 16:38:35

C#读取XML节点

2009-09-11 10:59:06

Effective C调用Dispose()

2009-08-05 09:30:39

C#调用DLL函数

2009-08-05 09:40:02

C#调用DLL函数
点赞
收藏

51CTO技术栈公众号