.NET 3.5 Language Enhancements

Comments 56

Share to social media

While Visual Studio 2008, the several variations of LINQ, and the ADO.NET Entity Framework are getting a lot of attention in the upcoming .NET Framework 3.5, there are also several key language enhancements on the near horizon. Many of the language enhancements (which will be found in VB 9 and C# 3.0) are the foundation of these more prominent new technologies. This article is a primer for some of the key enhancements that will be introduced with the .NET Framework 3.5 and how they relate to each other.

There are several .NET language enhancements to be introduced with Visual Studio 2008 including implicitly typed variables, extension methods, anonymous types, object initializers, collection initializers and automatic properties. These language enhancements, along with features like generics, are critical to the use of some of the new features, such as LINQ with the ADO.NET Entity Framework. What can be confusing is that these features are often referred to in the same conversation as LINQ. Because of this relation by association, you may be led to believe that these features are part of LINQ. They are not; they are part of the .NET Framework 3.5 and the VB 9 and C# 3.0 languages. They are very valuable in their own rights as well as playing a huge role for LINQ.

This article will demonstrate and discuss several key language features including:

  • Automatic Property setters/getters
  • Object Initializers
  • Collection Initializers
  • Extension Methods
  • Implicitly Typed Variable
  • Anonymous Types


Figure 1 – Many of the New Language Enhancements

Automatic Properties

Since creating classes by hand can be monotonous at times, developers use either code generation programs and IDE Add-Ins to assist in creating classes and their properties. Creating properties can be a very redundant process, especially when there is no logic in the getters and setters other than getting and setting the value of the private field. Using public fields would reduce the code required, however public fields do have some drawbacks as they are not supported by some other features such as inherent data binding.

One way to get around having to type the code for a private field and its public property getter and setter is to use a refactoring tool. However, there is a new language feature called Automatic Properties that allows you to type less code and still get a private field and its public getter and setter. You declare the automatic property using a shortcut syntax and the compiler will generate the private field and the public setter and getter for you. For example, Figure 2 shows a Customer class that has several private fields that are exposed through a series of corresponding public properties. This class has 4 properties including one that is of the class type Address.

Figure 2 – Customer Class using Explicit Fields, Getters and Setters

Figure 3 shows how the same result can be achieved through automatic properties with less code than Figure 2. The Customer class in Figure 3 uses automatic properties to create the class’ properties without writing all of the code to declare a field and its property getter and setter.

Figure 3 – Customer Class using Automatic Properties

Object Initializers

It is often helpful to have a constructor that accepts the key information that can be used to initialize an object. Many code refactoring tools help create constructors like this with .NET 2. However another new feature coming with .NET 3.5, C# 3 and VB 9 is object initialization. Object Initializers allow you to pass in named values for each of the public properties that will then be used to initialize the object.

For example, initializing an instance of the Customer class could be accomplished using the following code:

However, by taking advantage of Object Initializers an instance of the Customer class can be created using the following syntax:

The syntax is to wrap the named parameters and their values with curly braces. Object Initializers allow you to pass in any named public property to the constructor of the class. This is a great feature as it removes the need to create multiple overloaded constructors using different parameter lists to achieve the same goal. While you can currently create your own constructors, Object initializers are nice because you do not have to create multiple overloaded constructors to handle the various combinations of how you might want to initialize the object. To make matters easier, when typing the named parameters the intellisense feature of the IDE will display a list of the named parameters for you. You do not have to pass all of the parameters in and in fact, you can even use a nested object initialize for the BusinessAddress parameter, as shown below.

Collection Initializers

Initializing collections have always been a bother to me. I never enjoy having to create the collection first and then add the items one by one to the collection in separate statements. (What can I say, I like tidy code.) Like Object Initializers, the new Collection Initializers allow you to create a collection and initialize it with a series of objects in a single statement. The following statement demonstrates how the syntax is very similar to that of the Object Initializers. Initializing a List<Customer> is accomplished by passing the instances of the Customer objects wrapped inside of curly braces.

Collection Initializers can also be combined with Object Initializers. The result is a slick piece of code that initializes both the objects and the collection in a single statement.

The List<Customer> and its 3 Customers from this example could also be written without Object Initializers nor Collection Initializers, in several lines of code. The syntax for that could look something like this without using these new features:

Extension Methods

Have you ever looked through the list of intellisense for an object hoping to find a method that handles your specific need only to find that it did not exist? One way you can handle this is to use a new feature called Extension Methods. Extension methods are a new feature that allows you to enhance an existing class by adding a new method to it without modifying the actual code for the class. This is especially useful when using LINQ because several extension methods are available in writing LINQ query expressions.

For example, imagine that you want to cube a number. You might have the length of one side of a cube and you want to know its volume. Since all the sides are the same length, it would be nice to simply have a method that calculates the cube of an integer. You might start by looking at the System.Int32 class to see if it exposes a Cube method, only to find that it does not. One solution for this is to create an extension method for the int class that calculates the Cube of an integer.

Extension Methods must be created in a static class and the Extension Method itself must be defined as static. The syntax is pretty straightforward and familiar, except for the this keyword that is passed as the first parameter to the Extension Method. Notice in the code below that I create a static method named Cube that accepts a single parameter. In a static method, preceding the first parameter with the this keyword creates an extension method that applies to the type of that parameter. So in this case, I added an Extension Method called Cube to the int type.

When you create an Extension Method, the method sows up in the intellisense in the IDE, as well. With this new code I can calculate the cube of an integer using the following code sample:

As nice as this feature is I do not recommend creating Extension Methods on classes if instead you can create a method for the class yourself. For example, if you wanted to create a method to operate on a Customer class to calculate their credit limit, best practices would be to add this method to the Customer class itself. Creating an Extension method in this case would violate the encapsulation principle by placing the code for the Customer’s credit limit calculation outside of the Customer class. However, Extension Methods are very useful when you cannot add a method to the class itself, as in the case of creating a Cube method on the int class. Just because you can use a tool, does not mean you should use a tool.

Anonymous Types and Implicitly Typed Variables

When using LINQ to write query expressions, you might want to return information from several classes. It is very likely that you’d only want to return a small set of properties from these classes. However, when you retrieve information from different class sources in this manner, you cannot retrieve a generic list of your class type because you are not retrieving a specific class type. This is where Anonymous Types step in and make things easier because Anonymous Types allow you to create a class structure on the fly.

Notice that the code above creates a new instance of a class that describes a dog. The dog variable will now represent the instance of the class and it will expose the Breed, Coat and Ferocity properties. Using this code I was able to create a structure for my data without having to create a Dog class explicitly. While I would rarely create a class using this feature to represent a Dog, this feature does come in handy when used with LINQ.

When you create an Anonymous Type you need to declare a variable to refer to the object. Since you do not know what type you will be getting (since it is a new and anonymous type), you can declare the variable with the var keyword. This technique is called using an Implicitly Typed Variable.

When writing a LINQ query expression, you may return various pieces of information. You could return all of these data bits and create an Anonymous Type to store them. For example, let’s assume you have a List<Customer> and each Customer has a BusinessAddress property of type Address. In this situation you want to return the CompanyName and the State where the company is located. One way to accomplish this using an Anonymous Type is shown in Figure 4.

Figure 4 – Using Anonymous Types with LINQ

Pay particular attention to the select clause in the LINQ query expression. The select clause is creating an instance of an Anonymous Type that will have a Name and a State property. These values come from 2 different objects, the Customer and the Address. Also notice that the properties can be explicitly renamed (CompanyName is renamed to Name) or they can implicitly take on the name as happens with the State property. Anonymous Types are very useful when retrieving data with LINQ.

Wrapping Up

There are a lot of new language features coming with .NET 3.5 that both add new functionality and make the using of existing technologies easier. As we have seen in the past, when new technologies have been introduced, such as with generics, they often are the precursors to other technologies. The introduction of Generics allowed us to create strongly typed lists. Now because of those strongly typed lists of objects we will be able to write LINQ query expressions against the strongly typed objects and access their properties explicitly even using intellisense. These new features such as Object Initializers and Anonymous Types are the building blocks of LINQ and other future .NET technologies.

About the author

John Papa is a Senior .NET Consultant at ASPSOFT and an author of several data access technology books. John has over 10 years' experience in developing Microsoft technologies as an architect, consultant, and a trainer. He is the author of the Data Points column in MSDN Magazine and can often be found speaking at user groups, MSDN Web Casts, and industry conferences such as VSLive and DevConnections. John is a baseball fanatic who spends most of his summer nights rooting for the Yankees with his family and his faithful dog, Kadi. You can contact John at johnpapa.net.
His new book Data-Driven Services with Silverlight 2 has recently been published.

John Papa's contributions