c# object initializer complexity. best practice
Asked Answered
D

3

21

I was too excited when object initializer appeared in C#.

MyClass a = new MyClass();
a.Field1 = Value1;
a.Field2 = Value2;

can be rewritten shorter:

MyClass a = new MyClass { Field1 = Value1, Field2 = Value2 }

Object initializer code is more obvious but when properties number come to dozen and some of the assignment deals with nullable values it's hard to debug where the "null reference error" is. Studio shows the whole object initializer as error point.

Nowadays I use object initializer for straightforward assignment only for error-free properties.

How do you use object initializer for complex assignment or it's a bad practice to use dozen of assigments at all?

Thank you in advance!

Dilative answered 18/6, 2010 at 7:43 Comment(0)
C
18

Well, my main beef with object initializers is that they require a mutable type to start with: where possible, I prefer to use immutable types. Having said that, when an object initializer will work (e.g. for UI controls) I tend to use them.

I would possibly think twice if the values for the assignments were particularly complicated to compute - in particular, you have to be able to get the value in a single expression, and that may end up being less readable than computing it over several statements... but that's relatively rare in situations where this is feasible to start with.

I can't say I've had any problems with exceptions during property assignments with object initializers - it's just not something that comes up for me. If it did, I'd probably try to write a failing unit test anyway, at which point code usually becomes easy to fix without the debugger anyway.

Obviously moderation is always a good thing - I'm not suggesting taking this to extremes... but if you're setting a dozen properties, using an object initializer wouldn't be as much of a concern to me as having a dozen properties to set to start with. Are any of these dozen properties related? Should those be encapsulated together somehow? (In some cases that is fine - again, particularly with UI controls - but often it's not.)

Conspecific answered 18/6, 2010 at 7:49 Comment(2)
Usually I have such code when deal with business objects. Properties are populated from UI or come from different tables.Dilative
I tend to dislike object initializers in a DAO because you typically are getting the field from a reader and there is often something that could go wrong. You don't get any compiler safety . You can't really protect yourself with a unit test in this case because it becomes an integration test. Entities out the DB typically have a couple of fields associated with them. However if the assignments are trivial I will use an object initializer.Extroversion
C
4

If you're debugging your application then you should in most cases still be able to use VS' debugging tools to determine which assignment is causing the null reference.

However, if you split the assignment across multiple lines, I think VS will point to the right line when an exception is thrown:

MyClass a = new MyClass {
                    Field1 = Value1,
                    Field2 = Value2 };

Note: I don't do this myself, so be gentle about my (possibly) horrid line-breaking style.

Chiachiack answered 18/6, 2010 at 7:50 Comment(2)
No, no :) My studio highlight all the lines of object initializer when error come and I don't know what property has a problemDilative
I see. Then I guess for debugging purposes it's kind of a burden, unless you want to mouse over every expression you're assigning to the fields and see which one is null.Chiachiack
D
0

I never use it in code that is in development because as you point out, it is more difficult to debug.

For code that is well tested it can make the code more readable, although it could be argued that you shouldn't be messing with well tested and working code just to make it easier to read.

Remember, object initialisers where introduced to the language primarily to make the Linq syntax legal. That doesn't mean that it should be used more widely.

Having said that, if you are setting a bunch of properties on a number of controls, the indentation alone can make it a lot easier to get a quick overview of where certain controls are having their properties set.

Disproportion answered 18/6, 2010 at 7:49 Comment(3)
"you shouldn't be messing with well tested and working code just to make it easier to read" - using an object initializer is one of the safest refactorings there is. Are you not a fan of refactoring in general?Conspecific
Yes Jon, I agree with you very much on that point. Refactor where it makes sense to. If there are performance gains to be made and if code can be made safer and more robust. Certainly, changing types to be imutable as you mentioned in your answer is a best-practice. But just refactoring to use object initialisers is not often a good use of anyone's time.Disproportion
You could perfectly well use LINQ without object initializers (even anonymous types, because I think that's what you mean), although it would be a lot harder to read.Chiachiack

© 2022 - 2024 — McMap. All rights reserved.