zoukankan      html  css  js  c++  java
  • C#中Finalize方法的问题

    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

     

  • 相关阅读:
    结对-结对编项目贪吃蛇-开发环境搭建过程
    gitbook serve运行报错TypeError: cb.apply is not a function
    iOS 工程添加的framework转成pod形式加入
    selector not recognized
    Errors were encountered while preparing your device for development. Please check the Devices and Simulators Window.
    podspec 添加xcassets
    后缀自动机(SAM)构造实现过程演示+习题集锦
    数组中存在undefined,0,null,false等的情况该如何去除
    Uncaught TypeError: date.clone is not a function 【报错解决】
    React·前端URL参数丢失符号的解决办法
  • 原文地址:https://www.cnblogs.com/bruce1992/p/14153061.html
Copyright © 2011-2022 走看看