Порядок инициализации статических полей в статическом классе

учитывая следующий код:

public static class Helpers
{
   private static Char[] myChars = new Char[] {'a', 'b'};

   private static Int32 myCharsSize = myChars.Length;
}

Гарантируется ли, что myChars будет инициализирован до, я использую его длину для присвоения myCharsSize?


person Alex    schedule 29.09.2009    source источник


Ответы (3)


Да, они будут. См. Пункт 15.5.6.2 документа C # спецификация:

Инициализаторы переменных статического поля класса соответствуют последовательности назначений, которые выполняются в текстовом порядке, в котором они появляются в объявлении класса (§15.5.6.1). В частичном классе значение текстового порядка определяется §15.5.6.1. Если в классе существует статический конструктор (§15.12), выполнение инициализаторов статического поля происходит непосредственно перед выполнением этого статического конструктора. В противном случае инициализаторы статического поля выполняются во время, зависящее от реализации, до первого использования статического поля этого класса.

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

person Andrew Hare    schedule 29.09.2009
comment
@Marc - LOL, я написал "да", так что я буду первым, а потом вернусь с доказательствами. Поскольку я больше не могу быть FGTW, думаю, мне больше не стоит беспокоиться о том, чтобы быть первым: D - person Andrew Hare; 30.09.2009
comment
Вы можете найти текущую спецификацию на visualstudio.com/ условия лицензии /. - person jmlane; 15.05.2018
comment
А как насчет частичных классов? - person Sinjai; 14.02.2019

Хм ... Удивлен, что компилируется (есть, проверял). Я не знаю никаких гарантий, которые сделали бы это безопасным. Используйте статический конструктор ...


Изменить: я принимаю (см. лучший ответ выше) что будет работать; но моя идея с кодом - сделать его как можно более простым и очевидным. Если не очевидно, что это сработает (а этого не может быть, если вам нужно спросить), не пишите так ...

В частности, проблемы с опорой на порядок полей:

  • он может сломаться, если вы переместите код (что я часто делаю)
  • он может сломаться, если вы разделите код на partial классы

Мой совет остается: используйте для этого сценария статический конструктор.

person Marc Gravell    schedule 29.09.2009
comment
+1 Это разумный совет - просто потому, что вы можете что-то делать, не означает, что вы должны. Я думаю, что здесь можно использовать статический конструктор, хотя язык действительно поддерживает этот тип инициализации поля. - person Andrew Hare; 30.09.2009
comment
Хотя вы можете написать гораздо более сжатый код со статическими инициализаторами свойств / полей (вводя имя свойства один раз для каждого свойства, а не дважды - один раз в определении и один раз в функции статического инициализатора). В некоторых случаях это может быть разница между размещением исходного файла на одном экране или требованием прокрутки для полного просмотра. Зависит от вашей цели. Если вы хотите текстуально расположить свойства в порядке, отличном от того, в каком они должны быть инициализированы, тогда, да, вы можете выбрать только статическую функцию инициализатора, написанную вручную. - person binki; 21.02.2017

На первый взгляд я не был уверен, и мне пришлось попробовать это, чтобы увидеть, компилируется ли оно вообще.

Учитывая это, я бы инициализировал значение в статическом конструкторе.

person Jon Seigel    schedule 29.09.2009