C# 3.0 for mere mortals, part 4: Object and collection initializers

The fourth part in the C# 3.0 series will cover both object and collection initializers. In the previous part we have already seen a glimpse of object initialization.

Take this simple class:

public class Blog
  public string Title;
  private int _postCount;
  public int PostCount
    get { return _postCount; }
    set { _postCount = value; }

This class has two fields and one property, plus a default constructor provided by the compiler. The object initialization occurs where you instantiate a new object. Typically an object initializer looks like this:

Blog b = new Blog { Title = “hoi”, PostCount = 10 };

Look closely, because although the new keyword is used, the actual constructor call Blog() is not made. Instead, the initializer { } takes care of constructing the object.

The initializer takes name/value pairs for some or all of the fields and properties of the class. The order of the pairs is not important, but you can only specify those field and properties that are accessible by protection level. This rules out protected and private ones for most cases. The following initialization is incorrect, because _postCount is a private field.

Blog b = new Blog { Title = “hoi”, _postCount = 10 };

When one of the members is not a value type, but another class (never mind that strings are also reference types), things do not change very much. When the class Blog is expanded like so:

public class Blog
  // Other fields omitted …
  public Post Posting;

public class Post
  public string Text;

then you can initialize as follows:

Blog b = new Blog { PostCount = 10, Title = “My weblog”
                    Posting = newPost() };

or even using a nested initializer:

Blog b = new Blog { PostCount = 10, Title = “My weblog”
                    Posting = newPost{ Text = “Oops” } };

Pretty sweet. Also, when the constructor instantiates its reference types by itself or through a field initializer (yep, yet another initializer), the syntax changes ever so slightly:

public class Blog
  // …
  public Post Posting = new Post();

Blog b = new Blog { PostCount = 10, Title = “My weblog”, Posting = { Text = “Part 4 finally here” } };

Again, pay attention as to how the initialization of the already constructed Post object is performed: no call to newPost. You might be tempted to try the same for an ‘outer’ initialization.

Post Posting = { Text = “Oops, won’t compile” }

but that boat won’t rock.

Now that we have seen all this, collection initializers are a piece of cake. Every class that implements ICollection<T> can make use of a collection initializer. There aren’t that many in the FCL (with public constructors):

  • List<T>
  • SortedList<TKey, TValue>
  • Dictionary<TKey, TValue>
  • SortedDictionary<TKey, TValue>
  • LinkedList<T>
  • System.Collections.ObjectModel.Collection<T>
  • System.Collections.ObjectModel.ReadOnlyCollection<T>
  • System.Data.EntitySet<TEntity> !

List<byte> header = new List<byte> { 0xFF, 0xFF, 0xFF, 0xFF, 0x6D };
List<Post> postings = new List<Post>
      new Post { Text = “Article 1”},
new Post { Text = “Article 2” },
      new Post(),

The first one looks almost the same as an array initializer, except that List<T> is not an array. The second uses the nested object initializers and also shows that you can combine these with regular object and constructor calls.

Enough initializers for one day. Onto the next part: Lambda expressions. This is where it gets nasty.

Previous parts:

  1. Extensions methods
  2. Implicitly typed local variables and arrays
  3. Anonymous types
This entry was posted in Uncategorized. Bookmark the permalink.

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s