析构函数执行顺序?

幸运的利基

我知道C#中的析构函数没有执行顺序。

我在几个类中确实使用了以下结构,它是Desturct实例和静态信息:

public class MyClass
{
    private static readonly Destructor DestructorObject = new Destructor();

    ~MyClass()
    {
        Console.WriteLine("Destructor Called");
    }

    static void Main(string[] args)
    {
        var myClass = new MyClass();
    }

    private sealed class Destructor
    {
        ~Destructor()
        {
            Console.WriteLine("Static Destructor Called");
        }
    }
}

如前所述,消音器的顺序是不确定的。但是当我在许多类中使用此构造时,我发现在每个类中都有一个不变的顺序,即使我重新编译应用程序并再次运行它,该顺序也仍然存在。

意味着aMyClass1可能首先运行,~MyClass1而另一类MyClass2可能首先运行~Destructor

显然,每个班级都有一个“隐藏”命令,我可以相信吗?

尤瓦尔·伊茨恰科夫(Yuval Itzchakov)

显然,每个班级都有一个“隐藏”命令,我可以相信吗?

不,你不能。如果您看一下docs,他们会大喊:

即使一个对象引用另一个对象,也不能保证两个对象的终结器以任何特定顺序运行也就是说,如果对象A引用了对象B并且都具有终结器,则对象B的终结器启动时可能已经终结了对象B。

在正常的执行流程中依靠这样的实现细节将是一个非常糟糕的主意。

鉴于某些原因,你选择使用终结作为清理静态资源的一种方式,你首先应该想到,如果这是正确的做法,并考虑到所有的析构函数意味着,然后至少实现IDisposable,并给来电者有机会处置资源,GC.SupressFinalize以及调用

在对象中使用此方法作为通用方法也将延长对象的寿命,因为只有将对象移到f可达队列并依靠终结器线程实际清理它们之后,它们才有资格进行收集。根本不能保证。

埃里克·利珀特(Eric Lippert)最近(2015年5月18日)开始了一个名为“当您所知道的一切都出错时谈论终结器神话”的系列,我建议您看看。

编辑:

该系列的有趣的Erics第二篇帖子(今天发布)回答了这个问题:

误解:终结器以可预测的顺序运行

假设我们有一棵对象树,所有对象都可以终结,并且都在终结器队列中。不需要树从根到叶,从叶到根或任何其他顺序定型。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章