Подтвердить что ты не робот

Constructor vs Object Initializer Precedence в С#

Недавно я изучал инициализатор объектов в С#, но теперь мне интересно, как это работает, когда оно конфликтует с конструктором.

public class A
{
    public bool foo { get; set; }
    public A()
    {
        foo = true;
    }
    public A(bool bar)
    {
        foo = bar;
    }
}

Что происходит, когда я пытаюсь это сделать?

public class B
{
    a = A() {foo = false};
    b = A(true) {foo = false};
}

Является ли по умолчанию конструктором хороший способ запустить bool, который может быть изменен?

public A(bar=true)
{
    foo = bar;
}
4b9b3361

Ответ 1

Из документации:

Компилятор обрабатывает инициализаторы объектов, сначала обращаясь к конструктор экземпляра по умолчанию, а затем обработку элемента инициализацию.

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

Для второй части вашего вопроса: это скорее вопрос стиля, но если у вас есть ключевое свойство, я бы не создал конструктор со значением по умолчанию. Сделать код клиента установленным значением явно. Я также не уверен, зачем делать что-то вроде этого: b = A(true) {foo = false}; было бы хорошей идеей, если вы не участвуете в конкурсе по обфускации кода.

Немного осторожности:

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

Ответ 2

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

enter image description here

Ответ 3

Сначала создается конструктор, а затем инициализатор объекта. Просто помните, что

a = new A() { foo = false };

совпадает с

var temp = new A();
temp.foo = false;
a = temp;

Ответ 4

b = new A(true) {foo = false};

является эффективным для:

A temp = new A(true);
temp.foo = false;
A b = temp;

где temp - недоступная в противном случае переменная. Конструктор всегда выполняется первым, за которым следуют любые инициализированные свойства.

Ответ 5

По сути, Павел уже связан:

Из Спецификация языка С# 5 (7.6.10.1)

Processing of an object creation expression that includes an object initializer or
collection initializer consists of first processing the instance constructor and then
processing the member or element initializations specified by the object initializer or
collection initializer.