Bill Blogs in C#

Bill Wagner discusses C#, LINQ, and other items of interest

Code from Lightning Talk: Compiler Tricks

My last Lightning Talk should how you can mix constructor calls and object initializers. It's a useful technique that can keep you from writing too much code you don't need.

To see what I mean, start with this simple person class:

   1: class Person
   2: {
   3:     public string FirstName
   4:     {
   5:         get;
   6:         set;
   7:     }
   8:  
   9:     public string LastName
  10:     {
  11:         get;
  12:         set;
  13:     }
  14:  
  15: }
  16:  

You can initialize a person using the new object initialier syntax:

   1: Person someone = new Person{ FirstName = "SomeOne", LastName = "Else"};

The compiler calls the default constructor, so the above line actual calls the default constructor. It's as though you've written this (which is valid as well):

   1: Person someone = new Person(){ FirstName = "SomeOne", LastName = "Else"};

That can be very useful if you later decide that you have some property of the object that should be immutable. For example, you might add a property for the social security number. People can change their name, but not the soc numbers. You'd modify the person class to look like this:

   1: class Person
   2: {
   3:     public string FirstName
   4:     {
   5:         get;
   6:         set;
   7:     }
   8:  
   9:     public string LastName
  10:     {
  11:         get;
  12:         set;
  13:     }
  14:  
  15:     public string SSN
  16:     {
  17:         get;
  18:         private set;
  19:     }
  20:     public Person(string ssn)
  21:     {
  22:         SSN = ssn;
  23:     }
  24: }

Now, you have to make use of the fact that you can explicitly call a constructor. You'd do something like this:

   1: Person someone = new Person("000-00-0000"){ FirstName = "SomeOne", LastName = "Else"};

The advantage is that the class writer does not need to create extra constructors to specify combinations of the different properties you'd like to set at initialization time. You can specify only the parameters that must be used to set immutable state, and let the caller specify whatever set of mutable properties using the object initializer syntax.

You can also make use of this when you create a collection. You can use the constructor to specify a capacity and still use the collection initializer syntax to add the elements:

   1: List<string> names = new List<string>(100) 
   2: { 
   3:     "string one", 
   4:     "string two" 
   5:     // 98 other strings elided.
   6: };
It's a nice little bit of syntactic sugar to apply at the right time.
Published Sat, Aug 30 2008 5:53 PM by wwagner

Comments

# re: Code from Lightning Talk: Compiler Tricks@ Tuesday, September 02, 2008 2:49 PM

I didn't realize you could initialize objects in this manner until seeing your post. I fired up Visual Studio and gave it a shot. You mentioned "new" object initializer syntax in your post, but I compiled under .NET Framework 2.0 in VS 2008 and it appeared to work. Am I missing something? When was this feature introduced?

Thanks.

by Mark

# re: Code from Lightning Talk: Compiler Tricks@ Wednesday, September 03, 2008 8:14 AM

Mark,

Object Initializers are a compile time feature in C# 3.0. That means you can use it in projects that target the 2.0 framework. The framework targeting feature ensures that you don't use features in the newer versions of the framework that may not be installed on your target machine.

by wwagner