|
In the new version of C# (the one that comes with Visual Studio 2008) gives you the ability to instantiate a class and then practically in the same breath initialize any public properties or fields with new values. In current and previous versions of C#, you might have to do something like this:
Customer x = new Customer();With the new version of C#, you can simplify the above syntax to:
x.FirstName = "Bob";
x.LastName = "Johnson"; ...
Customer x = new Customer() { FirstName = "Bob", LastName = "Johnson" }; Obviously the second syntax is more compact, saves typing, and some might argue that the second syntax can be easier to read. In fact, a lot of C# programmers are saying that Object Initializers finally give us a syntax similar to the VB/VB.NET "with" syntax.The purpose of this bog post isn't to debate whether the syntax is nicer, because that's pretty obvious. However, the problem with this syntax and so many other "hello world" type samples is that, if taken in a vacuum, inexperienced or undisciplined programmers will run with it and completely abuse it.
There is a reason why we all spend so much time figuring out which constructors we need to provide in our classes, but it really boils down to the fact that as the class developer and designer, we know which properties need to be initialized at construction-time and which ones are optional. If we really do have required properties then we've probably been really good little programmers and not defined a default constructor (unless your class needs to be serialized or something...). This way, you can make the required values part of the constructor, and leave the optional stuff in the initializer, as shown in the sample below where the required field (customer ID) is part of the constructor and the class has no public default constructor:
Customer x = new Customer(9056)This second use of initializers I think makes a lot more sense. I love the new initializers, and I think the syntax is extremely handy and I use it everywhere. I just think that initializers expose a larger problem - abuse of default constructors. IMHO, you should only have a default constructor if your class requires no initialization step (for example, a pure state class or persistence-ignorant model object with no required fields, etc) or if your class needs to be serialized or some other exception.
{
FirstName = "Bob",
LastName = "Johnson"
};
So, in conclusion, I love object intializers, but coupled with inappropriate use of default constructors, I think it can create situations where the use of object initializers has exposed flaws in the original class design. Like any powerful new tool, it should be used wisely, despite the temptation to try out the new tool on everything you can find :) In short, if you're already following good practices, initializers will make your code more readable. If you're not, initializers can create hidden states or "magic states" (where the system depends on some un-documented sequence of property setters being called).
Yeah I'm with you on this... didn't we discuss this? ;-)
Object initializers are definitely nice syntax-wise, but I would REALLY
like a way to know, inside the class being initialized, when an initializer
has finished, so that I can do some final initialization to the class after
all the members have been set up... so far it doesn't look like this is
possible.