析构函数执行顺序?

Luc*_*key 3 c# destructor

我知道c#中的Destructors没有执行顺序.

我在几个类中使用以下结构,它是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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

正如我上面提到的,Destuctors的顺序是一个统一的.但是当我在许多类中使用这个构造时,我发现,在每个类中都有一个不变的顺序,即使我重新编译应用程序并再次运行它也会保留.

意味着a MyClass1alaways可能首先运行~MyClass1而另一个类MyClass2可能首先运行~Destructor.

由于每个班级显然都有"隐藏"的订单,我能相信吗?

Yuv*_*kov 7

由于每个班级显然都有"隐藏"的订单,我能相信吗?

不,你不能.如果你查看文档,他们会尖叫:

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

依赖这样的实现细节作为正常执行流程的一部分将是一个非常糟糕的主意.

看到由于某种原因你选择使用终结器作为清理静态资源的方法,你首先应该考虑这是否是正确的方法,考虑到析构函数所暗示的一切,然后至少实现IDisposable并给予调用者一个机会处理资源,也叫GC.SupressFinalize.

在对象中使用它作为一种常见的方法也会导致对象延长它们的寿命,因为它们只有在移动到f-reachable队列后才有资格进行收集,并依赖终结器线程来实际清理它们,根本不保证.

Eric Lippert最近(18-05-2015)开始了一个名为" 当你所知道的一切都是错误的谈论终结者神话"时,我建议你看看.

编辑:

有趣的是,Erics 在该系列中的第二篇文章(今天发布)回答了这个问题:

神话:终结者以可预测的顺序运行

假设我们有一个对象树,所有对象都可以终结,并且都在终结器队列中.从树根到树叶,从树叶到树根,或任何其他顺序,都没有要求树最终确定.