Thought: Are object initializers the end of convenience constructors?
Often when creating classes, we add a number of constructors to the class that are usually just there for convenience’s sake; that is, to make life easier for the developers using the class. Take the following code:
public class Contact
{
private string _firstName;
private string _lastName;
private string _emailAddress;
public Contact()
{
}
public Contact(string firstName, string lastName)
: this(firstName, lastName, null)
{
}
public Contact(string firstName, string lastName, string email)
: this()
{
this.FirstName = firstName;
this.LastName = lastName;
this.EmailAddress = email;
}
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
public string EmailAddress
{
get { return _emailAddress; }
set { _emailAddress = value; }
}
}
In this code, there is no real reason why the FirstName, LastName and EmailAddress properties have to be set when the object is constructed - they could be set immediately after by calling the property setters with no adverse side effects. The additional constructors are just there for convenience.
C# 3.0 introduces object initializers, which were originally introduced for anonymous types, as in the following code:
var unknown = new { Something = 42, SomethingElse = "Hello" };
Console.Write(unknown.SomethingElse);
Object initializers can also be used for known types. Instead of using the constructors from the first example, we could simply write:
Contact paul = new Contact { FirstName="Paul", LastName="Stovell" };
When I started using VS 2008 Beta 2 and C# 3.0, I almost immediately stopped writing convenience constructors, and fell in love with object initialization syntax. Not only do they make the code for those using it easier (since the properties are named), but they also make the code for the class simpler (overloaded constructors can easily spiral out of control when there are lots of properties, meaning lots of overloads).
I predict that when the market adopts C# 3.0, parameterized constructors that exist just for convenience will be a thing of the past.
Filed under: C#

At first I was excited about the introduction of the object initializers and their potential of helping to eliminate convenience constructors. Until, I recently discovered that one of the greatest benefits of convenience constructors is that they work with intellisense to guide a developer to initialize the object with a set of properties that result in a valid configuration of the object.
I have to agree with Adam. Constructors are not always about convenience, sometimes the constructor is the definitive list of what information the object needs to be valid and to do it’s job.
As developers get used to these object initializers there will no doubt be many classes written without parameter-taking constructors that offer no insight as to which properties are essential to be valid.
In fact, even without object initializers we already have this problem. Take a look at the HtmlControls in .NET. Despite the HTML standards listing ‘required’ properties there is no constructor that sets them meaning you have to keep flipping back and forth to the spec to ensure valid XHTML/HTML.
No doubt that will be addressed by an attribute in .NET 4.0 called [RequiredInitializationProperty] that further complicates everything.
[)amin
I agree with other’s opinion, constructor parameters are a good way to indicate what parameters are necessary to properly initialize the instance.
Also object initializers can set read-only property, while using ctors you can pass a variable that after initializing the instance can be exposed for convenience.
> I predict that when the market adopts C# 3.0, parameterized constructors that exist just for convenience will be a thing of the past.
I hope not. For the same reasons listed above. The syntax looks nice, but it is a really bad idea for an OO perspective. You should always make the users of your class construct it in a valid state.
I’m going to add a “me too” agreement with the other commentors. One of the major gripes I have with XAML is that it doesn’t have good support for parameterized constructors. This means that its way to easy for developers to create instances that aren’t properly initialized - which in turn means the developer ends up having to check for required parameter/property values and throw InvalidOperationExceptions where required.
Whilst I don’t mind having the Object initializer feature I certainly hope it doesn’t stop developers from writing good constructors - and not having parameterless constructors when necessary.
I agree that when values are required to put the object into a valid state, constructor parameters are required - that’s why I took the time to define a “convenience constructor” (e.g., fields aren’t required) over any constructor that takes parameters.
Damian, I’m going to disagree with the suggestion that HtmlControls should have constructors which force you to specify certain attributes. Just because the HTML standards say that an attribute is required doesn’t mean the class should. There are cases where you might not want to supply those fields - compatibility with a buggy browser, cases where you know a screen scraper requires your HTML to be in a certain format, etc. It is not the place of the .NET framework to make assumptions about how things will be used.
Paul, I think you know better. There is a huge difference between this:
public Contact() {}
public Contact(string firstName, string lastName) {…}
and this:
private Contact() {}
public Contact(string firstName, string lastName) {…}
Former is just a convenience in which case object initialiser somewhat makes sense. Latter, however, are implicit instructions to a class consumer to initialise mandatory properties which, as Corrado has mentioned, are often read-only. World of difference.
I love it. It helpes making code simpler and more readable. It looks a little bit like javascript, but you still get all the benefits of strict typing etc.
btw. automatic properties are a great feature, too. Even with the refactoring tools in VS (encapsulate field …) this is just one more pain taken away.
cheers
Florian
I like the ability to be able to name properties with object initializers, but it doesn’t work if you have read-only properties. I think I’ll be sticking with parameterized constructors.
The problem here is that you chose a bad example. A Contact is probably not valid if it doesn’t have a FirstName and LastName. So people gravitate towards criticizing the concept due to issues with invariants. If you’d exposed a single constructor requiring both of these, and illustrated the other contructor that also took an e-mail address versus:
new Contact(firstName, lastName) { EmailAddress = emailAddress };
you’d have had fewer people taking issue with the point. After all, you are very correct here, you just have to be careful to not enforce invariants at construction.