Создается ли объект, если инициализатор выбрасывает?

Я читал эту статью в блоге Джага Ригала Мне показалось, что то, что он предлагал, на самом деле не то же самое, что использование инициализатора объекта. Потом я понял, что на самом деле не знаю наверняка.

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


person Erik Funkenbusch    schedule 18.04.2011    source источник


Ответы (4)


Оператор инициализатора объекта, например var x = new Foo { Property1 = 5};, будет реализован примерно так:

Foo temp = new Foo();
temp.Property1 = 5;
x = temp;

Как видите, свойства в инициализаторе устанавливаются после создания объекта, однако для переменной не устанавливается значение полностью инициализированного объекта до тех пор, пока не будут установлены все свойства, поэтому, если исключение < strong>, созданный объект теряется, даже если исключение перехвачено (переменная останется null или любое другое значение, которое она имела раньше).

person Mark Cidade    schedule 18.04.2011
comment
Таким образом, результаты такие же, как если бы это был конструктор. Итак, мои мысли о том, что рекомендация Джага на самом деле не то же самое, верны. - person Erik Funkenbusch; 18.04.2011
comment
Результаты в основном такие же. Может быть разница в том, что осталось в памяти после исключения. Jag рекомендует, чтобы ReSharper ограничил предложения инициализатора 10 свойствами, иначе будет слишком сложно отлаживать, когда так много всего происходит в одной строке кода. - person Mark Cidade; 18.04.2011

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

Так, например, этот код:

var obj = new Model {
   FirstName = reader[0].ToString(),
   LastName = reader[1].ToString(),
   Age = Convert.ToInt32(reader[2].ToString())
};

Переписывается компилятором на:

var temp = new Model();
temp.FirstName = reader[0].ToString();
temp.LastName = reader[1].ToString();
temp.Age = Convert.ToInt32(reader[2].ToString())
var obj = temp;
person Hans Passant    schedule 18.04.2011

Объект будет построен, но инициализация не будет завершена. Инициализация - это всего лишь уловка компилятора; посмотрите на сгенерированный IL, и вы увидите то же самое в любом случае. Сообщение в блоге жалуется, что сложнее сказать, в какой строке произошло исключение, но лично у меня никогда не было такой трудности.

person Andy    schedule 18.04.2011

Вы все должны знать, что скомпилированный IL НЕ всегда одинаков !!

Разница заключается в конфигурациях сборки Debug / Release.

Если не верите, посмотрите в отражатель ...

person user2361430    schedule 08.05.2013