此代码实现的静态初始化顺序是否具体?

时间:2014-08-17 14:55:45

标签: c#

我的设计很大程度上依赖于静态初始化。我注意到,在一系列操作系统更新后,我的设计似乎在.NET Framework的某些版本(v <3.5)上失败,并且仅在Release配置下失败。

我认为我已经能够将问题缩小到与设计类似的代码块:

public abstract class Foo { public static object A; }
public class Bar : Foo { 
    public static object B = InitB();
    private static object InitB(){ return A }; }

public static void Main()
{
    Foo.A = new object();
    Bar bar = new Bar();
    Console.Write((bar.B==null).ToString());
}

在.NET 2.0上,在发布版本下,在我的系统上,我的代码正在打印true。而在.NET 4.5上,它正在打印false。以上代码的行为是否具体具体?

2 个答案:

答案 0 :(得分:1)

您的代码依赖于Bar在分配给Foo.A后调用的静态构造函数。语言规范并不能保证这一点。它只保证你实际编写一个静态构造函数,而不是编译器隐式生成一个:在这种情况下,它可能比你期望的更早被调用。

要确保您的代码在.NET Framework的所有有效实现中的行为方式相同,请添加静态构造函数。您不需要重新考虑您的初始化因素,他们可以保持原样。

public class Bar : Foo { 
    static Bar() { } // <-- add this
    public static object B = InitB();
    private static object InitB() { return A };
}

或者,重新编写代码,即使早期调用静态构造函数,它仍然可以正常工作。

答案 1 :(得分:0)

  

上述代码实现的行为是否具体

对于上面的示例,docs表明情况

  

如果类中存在静态构造函数,则在执行该静态构造函数之前立即执行静态字段初始值设定项。否则,静态字段初始值设定项在首次使用该类的静态字段之前的实现相关时间执行。

为了在.NET版本之间保持一致,并强制执行初始化顺序,您应该为这两个类添加一个静态构造函数。