Почему конструктор по умолчанию выполняется перед статическим конструктором?

Мне интересно, почему мой статический конструктор выводит default constructor Static Constructor, а не наоборот Static Constructor and Default constructor или просто Default constructor. Когда я использую статический конструктор, он должен сначала выполнить статический конструктор. Однако из приведенного ниже кода

Первый вопрос: почему конструктор по умолчанию вызывается перед статическим конструктором?

class Program
{
    static void Main(string[] args)
    {
        var test = Single.S;
    }
    class Single{
        static readonly Single s = new Single();

        public static Single S{
            get { return s; }
        }
        private Single(){
            Console.WriteLine("Default");

        }
        static Single(){
            Console.WriteLine("staic");
        }
    }
}

Второй вопрос: почему также вызывается конструктор Static Single?


person Shadman Mahmood    schedule 27.10.2018    source источник
comment
Если бы вы инициализировали класс экземпляра, сначала были бы инициализированы члены, а затем был бы запущен конструктор. Поскольку вы добавили статический конструктор, я думаю, происходит то же самое. Я думаю, что это то же самое.   -  person Llama    schedule 27.10.2018


Ответы (2)


В зависимости от Microsoft

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

class SimpleClass
{
    // Static variable that must be initialized at run time.
    static readonly long baseline;

    // Static constructor is called at most one time, before any
    // instance constructor is invoked or member is accessed.
    static SimpleClass()
    {
        baseline = DateTime.Now.Ticks;
    }
}

В этом случае статический конструктор будет вызываться перед конструктором по умолчанию.


но в этой строке

static readonly Single s = new Single();

вы используете "инициализацию статического поля"

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

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

тогда статический конструктор запускается перед вашим конструктором по умолчанию,

но когда он запускается, он использует new Single(), поэтому проходит через ваш нестатический путь конструктора.

Это приводит к вызову конструктора по умолчанию перед статическим конструктором.

Наконец, вы можете попробовать это, и вы увидите, что он выполнит статический конструктор перед конструктором по умолчанию.

private class Single
{
    private static readonly Single s;
    static Single()
    {
        Console.WriteLine("static");
        s = new Single();
    }
}

Ссылки

person Anas Alweish    schedule 27.10.2018

Первое, что происходит здесь при загрузке класса, это

static Single s = new Single();

C# выполняет статические инициализаторы, подобные этому, в том порядке, в котором они видны. Я не уверен, что эта точка упорядочения также применима к статическому конструктору, но из вашего теста кажется, что статический инициализатор действительно происходит до статического конструктора.

В любом случае, чтобы присвоить статические Single s, нужно сначала создать new Single(), что означает вызов нестатического конструктора. Я не уверен, что вы получите, если будете читать из Single.s в нестатическом конструкторе, но я ожидаю либо null, либо исключение.

person sjb-sjb    schedule 27.10.2018
comment
Последняя часть: это исключение NullReferenceException. - person Llama; 27.10.2018