O campo estático é inicializado posteriormente quando a classe possui um construtor estático

Executando este código simples:

class Program
{
    class MyClassWithStatic
    {
        public static int Number = SomeService.GetData();

        static MyClassWithStatic()
        {
            Console.WriteLine("static ctor runs");
        }
    }

    class SomeService
    {
        public static int GetData()
        {
            Console.WriteLine("GetDataRuns");
            return 42;
        }
    }        

    static void Main(string[] args)
    {
        InitService();

        var value = MyClassWithStatic.Number;
        Console.WriteLine(value);
    }

    private static void InitService()
    {
        Console.WriteLine("InitServiceRuns");
    }
}

A saída na minha máquina é esta:

InitServiceRuns
GetDataRuns
o ctor estático é executado
42.

Significando primeiro que o método InitService é chamado, então o campo estático do MyClassWithStatic é inicializado e, em seguida, o construtor estático é chamado (de fato, observando isso no ILSpy e IlDasm, podemos ver que a inicialização dos campos estáticos ocorre no início de o cctor)

Não há nada de interessante neste momento, tudo faz sentido, mas quando removo o construtor estático do MyClassWithStatic (para que o MyClassWithStatic se torne esse e todo o resto permaneça como antes)

class MyClassWithStatic
{
    public static int Number = SomeService.GetData();
}

A saída é esta:

GetDataRuns
InitServiceRuns
42.

Isso significa que, removendo o construtor estático, os campos estáticos são inicializados anteriormente. Como a inicialização faz parte do construtor estático (digo isso examinando-o com ildasm), o efeito é basicamente que o construtor estático é chamado anteriormente.

Então aqui está a questão:

Alguém pode explicar esse comportamento? Qual pode ser a razão disso?

Existe alguma outra coisa que pode mudar quando o construtor estático é chamado? (Por exemplo, anexar um criador de perfil ou executá-lo no IIS etc.) (comparei a depuração, modo de lançamento, x86, x64 e todos mostram o mesmo comportamento)

Algumas coisas gerais:

-Este estava em um aplicativo de console .NET 4.6. Também mudei para o .NET 2 (deve ser executado com um clr diferente e o comportamento é o mesmo, não faz diferença)

-Eu também tentei isso com o núcleo do .NET: com e sem um cctor, o método InitService é chamado primeiro.

-Agora estou absolutamente ciente deesta página:

O usuário não tem controle sobre quando o construtor estático é executado no programa.

E também sei que em um construtor estático há muitas coisas que você não deve fazer. Infelizmente, porém, tenho que lidar com um código em que essa parte está fora do meu controle e a diferença que descrevi faz uma enorme diferença. (E também passei por muitas questões SO relacionadas ao C # cctor.)

(E pergunta nº3 :) Então, a coisa toda que descrevi não é um pouco problemática?

questionAnswers(2)

yourAnswerToTheQuestion