Статическое поле инициализируется позже, когда класс имеет статический конструктор

Запустив этот простой код:

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

Вывод на моей машине такой:

InitServiceRuns
GetDataRuns
статический ход
42

Это означает, что сначала вызывается метод InitService, затем инициализируется статическое поле MyClassWithStatic, а затем вызывается статический конструктор (на самом деле, глядя на это в ILSpy и IlDasm, мы видим, что инициализация статических полей происходит в начале cctor)

В этом нет ничего интересного, все имеет смысл, но когда я удаляю статический конструктор MyClassWithStatic (таким образом MyClassWithStatic становится этим, а все остальное остается прежним)

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

Вывод такой:

GetDataRuns
InitServiceRuns
42

Это означает, что при удалении статического конструктора статические поля инициализируются ранее. Поскольку инициализация является частью статического конструктора (я говорю об этом, рассматривая его с помощью ildasm), эффект в основном заключается в том, что статический конструктор вызывается ранее.

Итак, вот вопрос:

Может кто-нибудь объяснить это поведение? В чем может быть причина этого?

Есть ли что-то еще, что может измениться при вызове статического конструктора? (Например, присоединение профилировщика или запуск его в IIS и т. Д.) (Я сравнил отладку, режим выпуска, x86, x64 и все показывают одинаковое поведение)

Некоторые общие вещи:

-Это было в консольном приложении .NET 4.6. Я также перешел на .NET 2 (должен работать с другим clr, и поведение такое же, это не имеет никакого значения)

-Я также пробовал это с ядром .NET: как с, так и без cctor, сначала вызывается метод InitService.

-Теперь я абсолютно в курсеэта страница:

Пользователь не может контролировать, когда статический конструктор выполняется в программе.

И я также знаю, что в статическом конструкторе есть много вещей, которые вы не должны делать. Но, к сожалению, мне приходится иметь дело с кодом, где эта часть находится вне моего контроля, и разница, которую я описал, имеет огромное значение. (И я также прошел через много вопросов, связанных с C # cctor ...)

(И Вопрос №3 :) Так не все ли это, что я описал, немного проблематично?

Ответы на вопрос(2)

Ваш ответ на вопрос