static class
Инициализировано в первый раз, когда упоминается одно из его полей, это легко.
Нет, все не так просто. Игнорируя вызовы методов, класс static
должен быть инициализирован непосредственно перед тем, как одно из его полей будет доступно в первый раз, если оно не отмечено beforefieldinit
. Если он отмечен beforefieldinit
, он может быть инициализирован раньше этого. (У Jon Skeet есть an article with lots more information about beforefieldinit
.)
Как это влияет на проверку инициализации класса? Поскольку CLR использует компиляцию JIT, она проверяет инициализацию класса при компиляции метода JIT. Если класс помечен beforefieldinit
, и он еще не был инициализирован, компилятор JIT инициализирует его сразу. Затем он фактически компилирует метод, где он может предположить, что класс уже инициализирован, поэтому никаких проверок не требуется.
Без beforefieldinit
, если класс еще не был инициализирован, компилятор JIT должен испускать код, который проверяет инициализацию перед каждым потенциальным первым доступом к полю. Но если класс уже инициализирован, а другой метод скомпилирован JIT, компилятор JIT больше не должен выставлять чеки.
Это может негативно отразиться на производительности в некоторых случаях. Из вышесказанного ясно, что для защиты от этого вам необходимо убедиться, что проблемные классы отмечены beforefieldinit
. И способ сделать это из C# - не иметь конструктора static
, используйте только инициализаторы полей static
.
Да, спасибо большое. Хотя я должен признать, что это кажется дорогостоящим проверять каждый раз при доступе к полю (например, в сравнении с C++) –
Чтобы быть понятным, эта проверка не выполняется при каждом доступе к классу. Состояние загрузки класса проверяется при загрузке класса. Если ваш класс A использует статическое свойство B.foo, то при использовании A его зависимости проверяются. Поэтому, когда инициализируется A, B также будет инициализирован. доступ к B.foo не дает таких проверок. – Kolja
Я сделал некоторые изменения для ответа, чтобы сделать его более понятным, когда эта проверка происходит. – Kolja