【问题标题】:Calling static methods from C# finalizer从 C# 终结器调用静态方法
【发布时间】:2020-07-01 22:07:00
【问题描述】:

Jeffrey Richter 在他的 CLR via C# 书中(如在线示例章节 Working with Types Requiring Special Cleanup 中所见)指出以下内容:

此外,CLR 不对 Finalize 方法的调用顺序做出任何保证。因此,您应该避免编写访问其他类型定义了 Finalize 方法的对象的 Finalize 方法;那些其他对象可能已经完成。但是,访问没有定义 Finalize 方法的值类型实例或引用类型对象是完全可以的。 调用静态方法时也需要小心,因为这些方法可以在内部访问已完成的对象,导致静态方法的行为变得不可预测

我理解上面引用的所有内容,但粗体的句子。如果静态方法只能使用其他静态成员引用由于生命周期而无法完成的对象,那么静态方法如何在内部使用已完成的对象,为什么调用实例方法是安全的?抱歉,我的结论可能是错误的,因此我将不胜感激对这个问题的任何解释。提前致谢。

【问题讨论】:

标签: c# .net static clr finalizer


【解决方案1】:

例如我们有两个类:

sealed class B
{
    private A _a = new A();

    ~B()
    {
        B.ManipulateA(_a);
    }

    public static void ManipulateA(A a)
    {
        //manipulations with "A" object
    }
}

sealed class A
{
    ~A() { }
}

所以如果CLR不保证Finalize方法的调用顺序,我们应该从BFinalizer中删除对静态方法的调用,因为我们的A对象可以在调用 B Finalizer 时已经完成,ManipulateA 可以尝试访问已完成的对象

我认为 Jeffrey 谈到了类似这个例子的内容。

【讨论】:

  • 我明白了,但是我可以将 ManipulateA 变成一个非静态方法并从终结器中调用它。我认为您描述了类似于此规则的内容:“因此,您应该避免编写访问其他类型定义了 Finalize 方法的对象的 Finalize 方法”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-14
相关资源
最近更新 更多