静态字段为什么在静态构造函数之前初始化?

12
以下代码:
static void Main(string[] args)
{
    Console.WriteLine("0");
    string h = Foo.X;
    Console.WriteLine("2");
}

public static class Foo
{
    public static string X = ((Func<string, string>)delegate(string g)
    {
        Console.WriteLine(g);
        return (g);
    })("_aaa");

    static Foo()
    {
        Console.WriteLine("ctor");
    }
}

将会打印:

0
_aaa
ctor
2

我了解beforefieldinit的行为(包括是否有静态构造函数等)。

我不理解的是为什么ctor(在输出中)在_aaa之后?这毫无意义,如果我想在构造函数中初始化变量怎么办?

问题:

为什么X的初始化在ctor之前?


对于非静态的字段和构造函数,情况当然是相似的:class Foo { public string X = "A"; public Foo() { X = "B"; } } 如果你执行(new Foo()).X,你会得到"B"而不是"A",因为“B”的赋值发生在后面(覆盖了第一个值)。 - Jeppe Stig Nielsen
@JeppeStigNielsen 感谢您的澄清。 - Royi Namir
1个回答

18
ctor 之所以在字段初始化器之后,是因为规定是这样的。根据 C# 规范(强调是我的):

10.5.5.1 静态字段的初始化:类的静态字段变量初始化器对应于一系列分配语句,它们按照它们在类声明中出现的文本顺序执行。如果类中存在静态构造函数(§10.12),则在执行该静态构造函数之前立即执行静态字段初始化器。否则,在使用该类的静态字段之前的某个实现相关时间执行静态字段初始化器。

如果您想完全控制初始化顺序,请将所有内容移至构造函数中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接