Monday, March 2, 2009

New Features in C# 3.0 / .NET 3.5 Part 1

In the first few blog posts, I’d like to start out by covering the new features introduced along with C# 3.0 and .NET 3.5. Some of these things are specific to the language itself, and can technically run against older versions of the Framework, while others are new things that are part of the actual .NET Framework 3.5. I’ll point out which ones which as I go.

Note: In order to take advantage of these features, Visual Studio 2008 is required. If you don’t already have a copy of VS2008, you can download the free express version here.

The first thing I’d like to talk about is a simple yet great feature called "Automatic Properties." The basic idea is as follows: Typically, when you want to have a public property on a class, you would have a private variable at the class level, and then have a get/set property for that variable:

   12         private string firstName;
   14         public string FirstName
   15         {
   16             get { return this.firstName; }
   17             set { this.firstName = value; }
   18         }

Nothing we haven’t done many many times. However, now, you can eliminate the private variable altogether, and just do this:

   12 public string LastName { get; set; }

Yup, that’s it! The interesting thing here is that it’s really just compiler trickery. Behind the scenes, the compiler does create a backing field for you, and a full blown Property. Let’s look at the IL generated by the compiler for both of those properties:

As you can see, the compiler generated a private string for me, and called it k_BackingField. Very cool. Trust me, once you start using these, you’ll never look back!

There is one thing to point out though; when using Automatic Properties, your get and set methods can have no logic whatsoever. If you want to do any validation in your getter or for example raise an event in your setter, you’ll need to do it the regular way and create your own backing variable.

Next up, is “Object Initializers.” Let’s create a simple class, we’ll call it Person. We’ll have three (Automatic) Properties. FirstName, LastName, and Age:

   34         public class Person
   35         {
   36             public string FirstName { get; set; }
   37             public string LastName { get; set; }
   38             public int Age { get; set; }
   39         }

Take note that this class has no constructor. Therefore, if I’d want to instantiate a Person object and set all it’s values, I’d have to do something like this:

   27          Person alex = new Person();
   28          alex.FirstName = "Alex";
   29          alex.LastName = "Friedman";
   30          alex.Age = 27;

Again, nothing fancy that you haven’t done before. However, say if we have an object that we need to set many properties on, this can get ugly quickly. Well, here’s the cool new way of doing it:

   27             Person alex = new Person
   28             {
   29                 FirstName="Alex",
   30                 LastName="Friedman",
   31                 Age=27
   32             };

You can set all properties this way, or only a select few that you want. Either way, it just saves you from having to type object. over and over again.

Intellisense makes it even easier for you. As soon as you open that first curly brace you get a list of all the available Properties you can set:

Taking these Object Initializers one step further, there’s also a new feature called “Collection Initializers.” Say you wanted to have a List with 3 Person objects. Here’s how you would normally do it:

   27             List<Person> people = new List<Person>();
   28             people.Add(new Person
   29             {
   30                 FirstName = "Alex",
   31                 LastName = "Friedman",
   32                 Age = 27
   33             });
   34             people.Add(new Person
   35             {
   36                 FirstName = "Jack",
   37                 LastName = "Bauer",
   38                 Age = 45
   39             });
   40             people.Add(new Person
   41             {
   42                 FirstName = "Cloe",
   43                 LastName = "O'Brien",
   44                 Age = 35
   45             });
   46             //Yes, before anyone asks, I'm a big fan of 24 :)

Now, you can do all that in one line when instantiating the collection:

   27             List<Person> people = new List<Person>
   28             {                
   29                     new Person { FirstName = "Alex",
   30                     LastName = "Friedman", Age = 27 },
   31                     new Person { FirstName = "Jack",
   32                     LastName = "Bauer", Age = 45 },
   33                     new Person { FirstName = "Cloe",
   34                     LastName = "O'Brien", Age = 35 }
   35             };

The last topic I’d like to cover in this post (which is probably also one of my personal favorites) is something called “Extension Methods.” In short, extension methods allow you to add functionality to existing classes. The best way to demonstrate, is by example. Very often, it’s useful to be able to check a string if it’s all numeric. (For validation, or whatever, doesn’t really matter). Extension methods now allow you to “add” these methods on to the string class as if it were part of the string class. Here’s how it’s done:

   48         public static class StringExtensions
   49         {
   50             public static bool IsNumeric(this string s)
   51             {
   52                 foreach (char c in s)
   53                 {
   54                     if (!char.IsDigit(c))
   55                     {
   56                         return false;
   57                     }
   58                 }
   59                 return true;
   60             }
   61         }

Simple method, just loop through the characters of the string, and if it’s not a digit return false, otherwise return true. (It doesn’t take into account $ signs and comas, but doesn’t really matter for this example). I’d like you to notice the syntax. When declaring an extension method, you use the “this” keyword in the method signature. Also, of note, extension methods MUST be declared in a static class, and MUST be static methods. Now here’s the cool part. Here’s how you’d use this method:

98 string number = "12345";

99 bool result = number.IsNumeric();

As you can see, it looks as if IsNumeric is actually part of the string class! This feature is extremely popular, and will be real important when I get to covering LINQ. There are many libraries out there that have tons of extension methods. Some are great, some are excessive in my opinion, but the point is all the same. Extension methods are awesome!

The thing to note about extension methods is that it's really just compiler trickery. The compiler basically takes the method call to the extension methods and turns it into something like this:

   37       string number = "12345";
   38       bool result = StringExtensions.IsNumeric(number);

I'll let you decide which way looks cooler and cleaner :)

One more thing about Extension Methods; here’s what it looks like in VS’s Intellisense:

That little blue arrow pointing down next to IsNumeric shows that this is an extension method.

Well, that’s it for the first post. I’ll cover more new topics in my next few posts.

No comments: