Оба утверждения, которые вы упомянули, верны и совпадают друг с другом. Я не уверен, почему вы думаете, что они противоречат друг другу.
Порядок выполнения следующий:
- Статические поля с инициализаторами.
- Статический конструктор.
Вышесказанное соответствует вашему второму утверждению. В первом утверждении просто упоминается, когда эти действия выполняются, т.е. до:
- Создается первый экземпляр класса.
- Ссылаются на любые статические члены.
На самом деле, приведенные выше условия можно считать гарантией для статических конструкторов, что инициализаторы статических полей будут выполнены, а статический конструктор будет вызван до того, как произойдет любое из двух событий (оператор 1).
В спецификации C# четко упоминается:
Статический конструктор класса выполняется не более одного раза в данном домене приложения. Выполнение статического конструктора инициируется первым из следующих событий, происходящих в домене приложения: Создается экземпляр класса. Ссылаются на любой из статических членов класса. Если класс содержит метод Main (раздел 3.1), с которого начинается выполнение, статический конструктор для этого класса выполняется до вызова метода Main. Если класс содержит какие-либо статические поля с инициализаторами, эти инициализаторы выполняются в текстовом порядке непосредственно перед выполнением статического конструктора.
Просто добавить, поскольку вы подчеркнули -
до создания первого экземпляра или ссылки на любые статические элементы.
Это просто означает, что можно ссылаться на статический член класса даже до создания экземпляра этого класса. Таким образом, даже в этом случае статический конструктор будет вызываться перед доступом к статическому члену.
Если вы видите код DavidG в его ответе, даже если класс не создается, но есть ссылка на один из статических членов, все равно инициализация статического поля происходит до того, за чем следует выполнение статического конструктора.
Пример:
public static class Test
{
public static int i = 10;
public static int j = new Func<int>(() => {
Console.WriteLine("Static field initializer called."); return 20;
})();
static Test()
{
Console.WriteLine("Static Constructor called.");
}
}
Теперь, если вы выполните:
Console.WriteLine(Test.i);
Вы получите следующий вывод:
Вызывается инициализатор статического поля.
Вызывается статический конструктор.
10
person
Shakti Prakash Singh
schedule
13.03.2017