объяснение инициализации статического поля и его требование

После просмотра стольких сложных вопросов, связанных с этим, я хочу спросить объяснение следующего кода, имеющего инициализацию статического поля. еще одна вещь, которую я хочу знать, это требование инициализации статического поля. В каких случаях это будет полезно??

using System;

class Test
{
    static void Main()
    {
        Console.WriteLine("{0} {1}", B.Y, A.X);
    }

    public static int F(string s)
    {
        Console.WriteLine(s);
        return 1;
    }
}

class A
{
    static A()
    { }

    public static int X = Test.F("Init A");
}

class B
{
    static B()
    { }

    public static int Y = Test.F("Init B");
}

Выход:

Инициализация Б

Инициал А

1 1

Если статический конструктор отсутствует, вывод может отличаться. Я не могу понять причину этого. Какая разница, которую инициализация статического поля привнесла в этот фрагмент? Может кто-нибудь, пожалуйста, помогите. Я новичок в С#.


person Neha    schedule 09.12.2014    source источник
comment
Пожалуйста, найдите время, чтобы отформатировать код при публикации. Его действительно трудно читать, когда нет отступов.   -  person Jon Skeet    schedule 09.12.2014
comment
я отправил его только после форматирования... где вы хотите сделать отступ... не могли бы вы упомянуть... это поможет мне в будущих сообщениях.   -  person Neha    schedule 09.12.2014
comment
Посмотрите, как сейчас выглядит пост — все отступы соответствующие. Теперь посмотрите на свой исходный пост (нажмите на отредактированный и посмотрите на версию 1), который был беспорядочным. Методы не имели отступа и т. д.   -  person Jon Skeet    schedule 09.12.2014
comment
спасибо @JonSkeet за отзыв. Я буду иметь это в виду в будущем. :) :)   -  person Neha    schedule 09.12.2014


Ответы (1)


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

Когда у него нет статического конструктора, среда выполнения имеет гораздо больше свободы — она должна выполнить инициализатор типа в какой-то момент до первого использования статического поля или до создания экземпляра, но это все. Вы даже можете наблюдать, как статические методы, которые не касаются статических полей, выполняются без выполнения инициализатора типа.

В вашем случае и A, и B имеют статические конструкторы, и порядок доступа к членам сначала B, затем A, следовательно, ваш вывод. Без этих статических конструкторов вы все равно гарантированно получите «1 1» в качестве последней строки, и вы все равно получите как «Init A», так и «Init B», но их порядок не будет гарантирован.

Это именно то, как задаются язык и среда выполнения - и обычно это не имеет никакого значения, поскольку обычно инициализаторы типов должны просто устанавливать тип, без каких-либо других побочных эффектов. Инициализаторы типов должны делать как можно меньше, в идеале — если они по какой-то причине не работают, тип никогда не будет использоваться; инициализаторы типов не повторяются.

Дополнительные сведения см. в моей beforefieldinit статье и в изменения инициализатора типов .NET 4.0 в блоге.

person Jon Skeet    schedule 09.12.2014