ninputer在关于“值类型的Finalize不会被调用”中(http://blog.joycode.com/lijianzhong/archive/2005/01/13/42991.aspx#FeedBack)评论到“VB对Finalize管的可松呢,可以直接重写、直接调用、允许不调用父类的Finalize,或者多次调用父类的Finalize等等…… 完全不像C#”。

其实C#的Finalize方法看起来只是比VB的好一点,但仍然有非常隐蔽的问题。问题如下。

首先来看如下的代码:

using System; 

public class Grandpapa 

     ~Grandpapa(){ Console.WriteLine("Grandpapa.~Grandpapa");} 


public class Parent:Grandpapa 

     ~Parent(){ Console.WriteLine("Parent.~Parent");} 


public class Son:Parent 

     ~Son(){ Console.WriteLine("Son.~Son");} 


public class App 

     public static void Main() 
     { 
         Son s=new Son(); 
  
         GC.Collect(); 
         GC.WaitForPendingFinalizers(); 
     } 
}

这段代码的运行结果毫无疑问是:

Son.~Son 
Parent.~Parent 
Grandpapa.~Grandpapa

这没什么问题。但是如果将Parent类重新定义如下,会出现什么情况呢?

public class Parent:Grandpapa 

     protected void Finalize(){ Console.WriteLine("Parent.Finalize");} 
}

运行结果变成了:

Son.~Son 
Parent.Finalize

情况已经有些不妙了,我在Parent中定义了一个“普通”的Finalize方法,竟然被它的子类Son的析构器给调用了?

当然Finalize方法在C#中并不是一个“普通”的方法,析构器编译后就是一个有上述签名的Finalize方法。但C#编译器并没有禁止我们定义“普通”的Finalize,

C#规范也没有指出定义这样的Finalize方法就是在定义一个析构器——实际上也不是,只是上述代码的表现如此——甚至还有这样一句诱人犯错的话:The compiler behaves as if this method(Finalize), and overrides of it, do not exist at all。分析IL代码可以看出,Parent中定义的“普通”的Finalize方法实际上“欺骗”了它的子类。它的子类只关心其父类是否定义了Finalize(当然签名要为上述形式)方法,它并不关心那个Finalize方法是否具有“析构器”语义。

如果上述代码的行为通过理性分析还算可以接受的话,那么下面代码的运行结果就令人眩晕了,将Parent类重新定义如下(在上面的基础上添加了一个virtual关键字):

public class Parent:Grandpapa 

     protected virtual void Finalize(){ Console.WriteLine("Parent.Finalize");} 
}

编译后运行结果如下:

Grandpapa.~Grandpapa

最新文章

  1. 前端学PHP之错误处理
  2. jQuery属性选择器.attr()和.prop()两种方法
  3. Angular2 从0到1 (二)
  4. 文件和目录之link、unlink、remove和rename函数
  5. hdu 1824
  6. 使用ntfs的磁盘映射功能
  7. hdu2492 Ping pong
  8. Maven的生命周期
  9. Chapter 1 Securing Your Server and Network(9):使用Kerberos用于身份验证
  10. IDEA Mybatis 找不到映射器xml文件
  11. windows 7 & protobuf 3.0 & python 3.5
  12. 数据结构与算法(C/C++版)【栈与队列】
  13. 爬取豆瓣电影TOP 250的电影存储到mongodb中
  14. vue2中使用transition
  15. 纯CSS制作图形效果
  16. struts2_Interceptor
  17. HTML语法分析
  18. [BZOJ4372]烁烁的游戏(动态点分治+线段树)
  19. zookeeper分布式锁和服务优化配置
  20. 子元素设置margin-top后,父元素跟随下移的问题

热门文章

  1. Python使用笔记005-文件操作(二)
  2. EXCEL:关键字有重复,其他信息一行多列显示
  3. C语言:文本文件和二进制文件
  4. Rust安装-运行第一个程序-hello_world
  5. 详解API Gateway流控实现,揭开ROMA平台高性能秒级流控的技术细节
  6. 前端开发入门到进阶第三集【sublime 的package control ——install package报错】
  7. python3中文件/IO编程
  8. Python3中datetime时区转换介绍与踩坑
  9. intouch制作历史报警查询(时间查询,筛选关键字)
  10. Pdb— Python的调试器