5

我在 Jag Reeghal 的博客上阅读了这篇文章,在我看来,他的建议与使用对象初始化器并不一样。然后我意识到我真的不确定。

当一个对象被构造时,使用对象初始化器,并且这些初始化器之一抛出(可能是空引用异常)......对象实际上是构造的吗?这基本上就像在构造函数中抛出的异常吗?还是对象完全构造,然后初始化?

4

4 回答 4

3

像这样的对象初始化语句var x = new Foo { Property1 = 5};将被实现为如下所示:

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

如您所见,initiallizer 中的属性是在构造对象后设置的,但是在设置所有属性之前不会将变量设置为完全初始化的对象,因此如果抛出异常,构造的对象就会丢失即使捕获到异常(变量将保留null或之前的任何值)。

于 2011-04-18T01:13:37.263 回答
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;
于 2011-04-18T01:24:33.193 回答
1

该对象将被构造,但初始化不会完成。初始化只是一个编译器技巧;查看生成的 IL,无论哪种方式,您都会看到相同的结果。博客文章抱怨说很难说出异常发生在哪一行,但就我个人而言,我从来没有遇到过这样的困难。

于 2011-04-18T00:54:33.193 回答
0

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

区别在于调试/发布构建配置。

如果你不相信我,请看一下反光板......

于 2013-05-08T08:14:46.297 回答