如果初始化器抛出异常,是否会构造对象?

发布于 2024-11-01 15:33:48 字数 285 浏览 1 评论 0原文

我在 Jag Reeghal 的博客上阅读了这篇文章在我看来,他的建议与使用对象初始值设定项确实不是一回事。然后我意识到我真的不太确定。

当使用对象初始值设定项构造对象时,这些初始值设定项之一会抛出异常(可能是空引用异常)...该对象实际上是构造的吗?这基本上就像构造函数中抛出的异常吗?或者是对象完全构造完毕,然后初始化?

I was reading This Article over on Jag Reeghal's blog and It seemed to me that what he was suggesting was really not the same thing as using an object initializer. Then I realized that I didn't really know for sure.

When an object is constructed, with object initializers, and one of those intitializers throws (maybe a Null Reference exception)... is the object actually constructed? Is this basically like an exception being thrown in the constructor? Or is the object fully constructed, and then initialized?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

金兰素衣 2024-11-08 15:33:48

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

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

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

An object initilizer statement like var x = new Foo { Property1 = 5}; will be implemented as something like this:

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

As you can see, the properties in the initiallizer are set after the object is constructed, however the variable isn't set to the fully-initialized object until all the properties are set, so if an exception is thrown, the constructed object is lost even if the exception is caught (the variable will remain null or whatever value it had before).

梦明 2024-11-08 15:33:48

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

例如,这段代码:

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;

It is fully constructed first, then initialized. You will however never get a reference to such an object if an exception is thrown, the compiler makes sure that your reference can only ever refer to a properly initialized object. It uses a temporary to guarantee this.

So for example, this code:

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

Is rewritten by the compiler to:

var temp = new Model();
temp.FirstName = reader[0].ToString();
temp.LastName = reader[1].ToString();
temp.Age = Convert.ToInt32(reader[2].ToString())
var obj = temp;
绾颜 2024-11-08 15:33:48

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

The object would be constructed, but the initialization would not complete. Initialization is just a compiler trick; look at the generated IL and you'll see its the same either way. The blog post is complaining that its harder to tell what line the exception occurred on, but personally I've never had that difficultly.

空‖城人不在 2024-11-08 15:33:48

你们都需要知道编译后的 IL 并不总是相同的!

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

如果你不相信我,请看看反光镜......

You all need to be aware the the compiled IL is NOT always the same!!

The difference is in Debug/Release build configurations.

Have a look in reflector if you dont believe me .....

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文