Static Feld wird später initialisiert, wenn die Klasse einen statischen Konstruktor hat

Mit diesem einfachen Code:

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

Die Ausgabe auf meinem Computer lautet wie folgt:

InitServiceRuns
GetDataRuns
static ctor rennt
42

Bedeutet, dass zuerst die InitService-Methode aufgerufen wird, dann das statische Feld von MyClassWithStatic initialisiert wird und dann der statische Konstruktor aufgerufen wird (wenn wir uns dies in ILSpy und IlDasm ansehen, können wir sehen, dass die Initialisierung der statischen Felder am Anfang stattfindet des cctor)

Es gibt an dieser Stelle nichts Interessantes, alles macht Sinn, aber wenn ich den statischen Konstruktor von MyClassWithStatic entferne (so wird MyClassWithStatic zu diesem und alles andere bleibt wie zuvor)

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

Die Ausgabe lautet wie folgt:

GetDataRuns
InitServiceRuns
42

Dies bedeutet, dass durch Entfernen des statischen Konstruktors die statischen Felder früher initialisiert werden. Da die Initialisierung Teil des statischen Konstruktors ist (ich sage dies, indem ich sie mit ildasm betrachte), wird der statische Konstruktor im Grunde genommen früher aufgerufen.

Also hier ist die Frage:

Kann jemand dieses Verhalten erklären? Was kann der Grund dafür sein?

Gibt es noch etwas, das sich ändern kann, wenn der statische Konstruktor aufgerufen wird? (Zum Beispiel Anhängen eines Profilers oder Ausführen in IIS usw.) (Ich habe Debug, Release-Modus, x86, x64 verglichen und alle zeigen dasselbe Verhalten.)

Einige allgemeine Dinge:

-Dies war in einer .NET 4.6-Konsolenanwendung. Ich habe auch auf .NET 2 gewechselt (sollte mit einer anderen clr laufen und das Verhalten ist das gleiche, es macht keinen Unterschied)

-Ich habe dies auch mit .NET Core versucht: Sowohl mit als auch ohne Cctor wird zuerst die InitService-Methode aufgerufen.

-Jetzt bin ich mir absolut bewusst,diese Seit:

Der Benutzer hat keine Kontrolle darüber, wann der statische Konstruktor im Programm ausgeführt wird.

Und ich weiß auch, dass es in einem statischen Konstruktor viele Dinge gibt, die Sie nicht tun sollten. Aber leider muss ich mich mit einem Code auseinandersetzen, bei dem dieser Teil außerhalb meiner Kontrolle liegt und der Unterschied, den ich beschrieben habe, einen großen Unterschied macht. (Und ich habe auch viele C # cctor-bezogene SO-Fragen durchlaufen.)

(Und Frage Nr. 3 :) Ist das Ganze, was ich beschrieben habe, nicht ein bisschen problematisch?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage