.NET 3.5: Types, Variables and Initializers

In this post I will wrap up some of the smaller but very useful new features of .NET 3.5/C# 3.0. Other features of .NET 3.5 I’ve already covered are Extension Methods and Lambda Expressions.

Object and Collection Initializers
This feature makes it easier to create objects and assign values to the properties of the objects. Until .NET 3.5 you either had to write code that created an object and initialized each property of the object, or use a constructor that takes a list of parameters (which had to change of be overloaded when a property was added). The same is true for creating lists of object, calling the Add method for every new object. The following example shows that object and collection initializers makes this easier, without the use of parameter constructors:

persons = new List<Person>
{
  new Person { Name = "Person I" },
  new Person { Name = "Person II" },
  new Person { Name = "Person III" },
  new Person { Name = "Person IV" }
};

In the example above the default constructor (without parameters) of Person will be used, witch will be executed before the property initialization. In case an alternative constructor is required, e.g. including a read only Id, the following syntax can be used:

Person person = new Person("NewGuid") { Name = "Person" };

Automatic Property get/set
The feature of automatic property takes away the burden of explicitly coding a private field and the get/set of a property, these are generated automatically by the compiler. The syntax is similar to the way of defining an abstract property or a property in an interface:

public class Person
{
  public string Name { get; set; }
}

If necessary the get/set can be changed to limit accessibility, e.g. Name { get; private set; }. Of course the object initializers as explained above cannot be used outside the class anymore.

Implicitly Typed Local Variables and Arrays
With implicitly typed variables the type of the variable is not defined up front but inferred by the compiler using the initialization of the variable. Basically this looks the same as defining the variable as an object, but there is a huge difference: after initialization the type is fixed and cannot be changed, e.g. by assigning a value of another type.

var a = 5;                  // int
var b = 5.5;                // double
var c = a + b;              // double
var d = new int[] { 1, 2 }; // int array
var e = new[] { 1, 2 };     // implicitly typed int array

foreach (var f in e)
  Console.WriteLine(f);

Using the var keyword is only allowed for local variables, they cannot be used as class variables for example. Also, they have to be initialized when they are declared.

The usage of implicitly typed variables as aboveis a bit doubtful I think, in fact it does make the code less readable (although IntelliSense can help you out). In relation to LINQ and Anonymous Types it does make more sense though, but more on that later.

Anonymous Types
Anonymous Types are objects that are defined and created on the fly using object initializers. The compiler actually creates properties of the initializers which can be used later on. The name of the type remains unknown and cannot be used within the program.

var p1 = new { Name = "Person I", City = "New York" };
Console.WriteLine(
  string.Format("{0} from {1}", p1.Name, p1.City));

Like implicitly Typed Variables the usage of Anonymous Types in this context doesn’t seem to be very useful because you really cannot do much with such an object. With LINQ the usage will be more frequent, e.g. to display a selection from an executed query:

var nyPersons = from q in persons
where q.Address.City == "New York"
select new { Name = q.Name, City = q.Address.City };

foreach (var nyp in nyPersons)
  Console.WriteLine(string.Format("{0} from {1}", nyp.Name, nyp.City));