Статический конструктор вызывается после конструктора экземпляра? - PullRequest
17 голосов
/ 11 ноября 2010

Дорогие все, вопрос, подобный этому, был уже задан , но среди ответов не было объяснения проблемы, которую я вижу.

Проблема: Руководство по программированию в C # гласит:

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

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

Давайте рассмотрим пример кода:

using System;

public class Test
{
    static public Test test = new Test();
    static Test()
    {
        Console.WriteLine("static Test()");
    }
    public Test()
    {
        Console.WriteLine("new Test()");
    }
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Main() started");
        Console.WriteLine("Test.test = " + Test.test);
        Console.WriteLine("Main() finished");
    }
}

Он выводит:

Main () запущено
new Test ()
static Test ()
Test.test = Test
Main () закончено

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

1 Ответ

27 голосов
/ 11 ноября 2010

Встроенные инициализаторы для полей static запускаются до явного конструктора static.

Компилятор превращает ваш класс во что-то вроде этого:

public class Test {
    .cctor {    //Class constructor
        Test.test = new Test();                //Inline field initializer
        Console.WriteLine("static Test()");    //Explicit static ctor
    }
    .ctor { ... }    //Instance constructor
}

Обратите внимание, что это не зависит от порядка объявления.

Цитировать spec :

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...