Jacob Carpenter’s Weblog

November 17, 2007

Named parameters and immutable type initialization

Filed under: csharp — Jacob @ 3:53 pm

Eric Lippert and Joe Duffy have each started blogging about immutable types (here and here, respectively). I’m a big fan of immutable types as the simplest solution to many thread-safety issues. And regardless of the number of threads your application utilizes, value types should always be immutable (and you should read the Framework Design Guidelines).

But there is a bit of a problem: C# 3.0 introduced "object initialization syntax."

Object initialization

Hopefully you’re familiar with the feature already, but here’s an example:

var settings = new XmlReaderSettings { CloseInput = true, IgnoreWhitespace = true };

XmlReaderSettings only has a default, parameterless constructor. The designers of the type expect you to individually set a number of properties on an instance before handing it off to XmlReader.Create. C# 3.0 now lets you initialize the instance in one statement.

Well, okay: you get to write one statement, but when compiled, that single statement turns back into a multi-step process of creating the instance and then setting the specified properties/fields individually. But it sure makes for nicer looking source.

Unfortunately, this compiler magic also means you cannot use object initialization syntax with immutable types. Since immutable types, by definition, don’t expose property setters, object initialization can’t compile.

Strangely enough, anonymous type instances (for which object initialization was created) are immutable. This post covers some of the changes to support the immutablity of anonymous types, including: "Anonymous type construction will no longer be realized as an Object initalizer (since the anonymous type is created in a single call), but as a single constructor call."

It’s a shame object initialization wasn’t changed to support immutablity, rather than anonymous types being modified to not use object initialization.

Named parameters

Object initialization isn’t unlike the concept of named parameters. In C# (with one caveat), all method/constructor parameters are positional parameters. That means that, while you give your method parameters descriptive names in your method declaration, the caller only cares about matching the order of their arguments to your method signature. Your method’s parameter names have no bearing on the caller.

With named parameters, parameters are allowed to be specified in any order and can even be optional. They can also make the source code more descriptive. Going back to our XmlReaderSettings example, imagine the constructor took a number of boolean parameters:

public XmlReaderSettings(bool closeInput, bool ignoreWhitespace /*, etc. */) { /*...*/ }

Our calling code would look like:

var settings = new XmlReaderSettings(true, true);

That’s obviously silly.

With named parameters, creation would look just like our object initialization example with parentheses instead of curly braces. There wouldn’t be any ambiguity about which properties were being set.

In some languages that don’t support named parameters (such as Ruby), people have used dictionaries to pass name/value pairs to methods. With C#’s collection initialization, a similar technique could be used. But .NET’s strong type system doesn’t support dictionaries with mixed value types very nicely. You could use a Dictionary<string, object>, but then value types would have to be boxed and there’d be casting to get values out… it’d be a mess.

Immutable type initialization

Hopefully, the future of C# includes stronger support for immutable types (including initialization scenarios). But until then, we can have some fun abusing anonymous types to meet our immutable type initialization needs. We’ll look at how in the next post.


1 Comment »

  1. […] our discussion from last time, we’re going to look at what we can do with object initialization syntax to enable immutable […]

    Pingback by Named parameters { Part = 2 } « Jacob Carpenter’s Weblog — November 19, 2007 @ 9:07 am

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: