El campo estático se inicializa más tarde cuando la clase tiene un constructor estático.

Al ejecutar este código simple:

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");
    }
}

El resultado en mi máquina es este:

InitServiceRuns
GetDataRuns
ctor estático se ejecuta
42

Es decir, primero se llama al método InitService, luego se inicializa el campo estático de MyClassWithStatic y luego se llama al constructor estático (de hecho, mirando esto en ILSpy e IlDasm podemos ver que la inicialización de los campos estáticos ocurre al comienzo de el cctor)

No hay nada interesante en este punto, todo tiene sentido, pero cuando elimino el constructor estático de MyClassWithStatic (entonces MyClassWithStatic se convierte en esto, y todo lo demás permanece como antes)

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

El resultado es este:

GetDataRuns
InitServiceRuns
42

Esto significa que al eliminar el constructor estático, los campos estáticos se inicializan antes. Dado que la inicialización es parte del constructor estático (lo digo al mirarlo con ildasm), el efecto es básicamente que el constructor estático se llama antes.

Así que aquí está la cuestión:

¿Alguien puede explicar este comportamiento? ¿Cuál puede ser la razón de esto?

¿Hay alguna otra cosa que pueda cambiar cuando se llama al constructor estático? (Por ejemplo, adjuntar un generador de perfiles o ejecutarlo en IIS, etc.) (comparé depuración, modo de liberación, x86, x64 y todos muestran el mismo comportamiento)

Algunas cosas generales:

-Este estaba en una aplicación de consola .NET 4.6. También cambié a .NET 2 (debería ejecutarse con un clr diferente, y el comportamiento es el mismo, no hace ninguna diferencia)

-También probé esto con .NET core: tanto con como sin cctor, el método InitService se llama primero.

-Ahora estoy absolutamente consciente deesta página:

El usuario no tiene control sobre cuándo se ejecuta el constructor estático en el programa.

Y también sé que en un constructor estático hay muchas cosas que no debes hacer. Pero desafortunadamente tengo que lidiar con un código donde esta parte está fuera de mi control y la diferencia que describí hace una gran diferencia. (Y también revisé muchas preguntas SO relacionadas con C # cctor ..)

(Y la pregunta nr3 :) Entonces, ¿no es un poco problemático todo lo que describí?

Respuestas a la pregunta(2)

Su respuesta a la pregunta