【问题标题】:Why CLR optimizing away unused static field with initialization?为什么 CLR 通过初始化优化掉未使用的静态字段?
【发布时间】:2015-10-01 10:47:12
【问题描述】:

让我们有两个代码sn-ps:

答:

public class Foo
{
    private static Bar _unused = new Bar();
}

乙:

public class Foo
{
    private static Bar _unused;

    static Foo()
    {
        _unused = new Bar();
    }
}

A 的情况下,CLR 甚至不会调用 Bar ctor(除非它是调试版本或附加了调试器),但是在 B 的情况下,它会被调用所有情况。

问题在于,在 Bar 构造函数中,可以进行调用,使该实例可从其他地方访问 - 最典型的是 事件订阅

所以:

  • 为什么案例 AB 的评估方式不同?
  • 为什么 CLR 在 A 的情况下根本不调用 Bar ctor - 因为它 在 ctor 完成和实例之前不应将其评估为垃圾 被分配到适当的字段?

【问题讨论】:

  • Foo 曾经在B 中使用过吗?
  • @HansPassant 在 sn-p A 中,Foo 在 IL 中被标记为 beforefieldinit。见this
  • @Lucas Trzesniewski 感谢您的出色回答!它实际上比接受的更正确(但遗憾的是,无法将 cmets 标记为答案)

标签: c# .net optimization initialization static-members


【解决方案1】:

如果你don't create a constructor:

类的静态字段变量初始化器对应于一系列赋值,它们按照它们在类声明中出现的文本顺序执行。如果类中存在静态构造函数(第 10.11 节),则在执行该静态构造函数之前立即执行静态字段初始值设定项。否则,静态字段初始化器在第一次使用该类的静态字段之前的依赖于实现的时间执行

如果你do have a static constructor:

静态构造函数用于初始化任何静态数据,或执行只需要执行一次的特定操作。它会在创建第一个实例或引用任何静态成员之前自动调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多