Is an object constructed if an initializer throws?
Asked Answered
B

4

5

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?

Boisvert answered 18/4, 2011 at 0:29 Comment(0)
U
3

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).

Unruffled answered 18/4, 2011 at 1:13 Comment(2)
So while different, the results are the same as if a constructor thows. So, my thoughts that Jag's recomendation is not really the same is correct.Boisvert
The results are mostly the same. There might be a difference in what's left in memory after the exception. Jag is recommending that ReSharper limit initializer suggestions to 10 properties otherwise it can be too hard to debug when so much is going on on a single line of code.Unruffled
V
2

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;
Vacancy answered 18/4, 2011 at 1:24 Comment(0)
P
1

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.

Padnag answered 18/4, 2011 at 0:54 Comment(0)
L
0

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 .....

Lalla answered 8/5, 2013 at 8:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.