См. мою статью по этому вопросу.
По сути, beforefieldinit
означает «тип может быть инициализирован в любой точке, прежде чем будут ссылаться на любые статические поля». В теории это означает, что он может быть очень ленивым инициализирован - если вы вызываете статический метод, который не касается никаких полей, JIT не нужно инициализировать тип.
На практике это означает, что класс инициализируется * на 1014 * раньше , чем это было бы в противном случае - это нормально для инициализации в начале первого метода, который может используйте это. Сравните это с типами, к которым не применено beforefieldinit
, к ним применена инициализация типа непосредственно перед первым фактическим использованием.
Итак, предположим, что у нас есть:
public static void DoSomething(bool which)
{
if (which)
{
FirstType.Foo();
}
else
{
SecondType.Bar();
}
}
Если к обоим типам применено beforefieldinit
(что в C # они делают по умолчанию, если у типа нет статического конструктора), то они оба будут инициализированы в начале DoSomething
метод (обычно - это не гарантировано). Если у них нет beforefieldinit
, то только один из них будет инициализирован на основе флага.
Вот почему обычно используется статический конструктор (даже пустой!), Когда реализует шаблон синглтона .