如果初始化器抛出异常,是否会构造对象?
我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
像
var x = new Foo { Property1 = 5}; 这样的对象初始化器语句将实现为如下所示:
正如您所看到的,初始化器中的属性是在对象构造之后设置的,但是在设置所有属性之前,变量不会设置为完全初始化的对象,因此如果抛出异常,即使异常发生,构造的对象也会丢失捕获(变量将保持
null
或之前的任何值)。An object initilizer statement like
var x = new Foo { Property1 = 5};
will be implemented as something like this: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).首先完全构造它,然后初始化。然而,如果抛出异常,您将永远不会获得对此类对象的引用,编译器确保您的引用只能引用正确初始化的对象。它使用临时来保证这一点。
例如,这段代码:
被编译器重写为:
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:
Is rewritten by the compiler to:
该对象将被构造,但初始化不会完成。初始化只是编译器的一个技巧;查看生成的 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.
你们都需要知道编译后的 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 .....