Почему инициализация статических полей происходит перед статическим конструктором?

Следующий код:

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?

Ответ 1

Причина ctor заключается в том, что после инициализаторов поля это так, как указано. Из спецификации С# (акцент мой):

10.5.5.1 Инициализация статического поля Статические инициализаторы переменных поля класса соответствуют последовательности присвоений, которые выполняются в текстовом порядке, в котором они отображаются в классе декларация. Если в классе существует статический конструктор (§ 10.12) выполнение инициализаторов статического поля происходит непосредственно перед выполнение этого статического конструктора. В противном случае статическое поле инициализаторы выполняются в зависящее от реализации время до первое использование статического поля этого класса

Если вы хотите иметь полный контроль над порядком инициализации, переместите его внутри конструктора.