如果初始化程序抛出,是否构造了一个对象?

时间:2011-04-18 00:29:37

标签: c# exception-handling object-initializers

我正在Jag Reeghal的博客上阅读This Article,在我看来,他所建议的内容与使用对象初始化程序实际上并不相同。然后我意识到我确实不确定。

构造对象时,使用对象初始化器,并且其中一个初始化器抛出(可能是Null Reference异常)......实际构造的对象是什么?这基本上就像是在构造函数中抛出的异常吗?或者对象是否完全构造,然后初始化?

4 个答案:

答案 0 :(得分:3)

var x = new Foo { Property1 = 5};这样的对象启动器语句将实现如下:

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

正如您所看到的,初始化器中的属性是在构造对象之后设置的,但是在 all 设置属性之前,变量未设置为完全初始化的对象,因此,抛出异常 ,即使捕获到异常,构造的对象也会丢失(变量将保持null或之前的任何值。)

答案 1 :(得分:2)

首先完全构造,然后初始化。但是,如果抛出异常,您将永远不会获得对此类对象的引用,编译器会确保您的引用只能引用正确初始化的对象。它使用临时来保证这一点。

例如,这段代码:

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;

答案 2 :(得分:1)

将构造对象,但初始化将无法完成。初始化只是一个编译技巧;看看生成的IL,你会看到它的相同方式。这篇博客文章抱怨说,更难说出异常发生在哪一行,但我个人从来没有这么难过。

答案 3 :(得分:0)

你们都需要知道编译的IL并不总是一样!!

区别在于Debug / Release构建配置。

如果你不相信我,请看一下反射器......