Friday, December 14, 2007

My Top 5 Favorite New C# 3.0/.NET 3.5 Framework Features

Partial Methods

This feature really puts the finishing touches on partial classes.  What this feature allows you to do is create an abstract-like method declaration in a partial class, and use it from a concrete operation in that class, with the expectation that the method will be implemented in another class.  In the below code, we've got a partial class defined, that has a constructor that calls a partial method which delegates the implementation to the another partial class.

partial class PartialMethod
{
    public PartialMethod()
    {
        GetTheStringImplementation();
    }
 
    public string Message { get; set;}
 
    partial void GetTheStringImplementation();
}
 
public partial class PartialMethod
{
    partial void GetTheStringImplementation()
    {
        this.Message = "This is the string from the concrete implementation.";
    }
}

You can see that this has pretty good potential for code generation scenarios, where you would need to provide hooks into your gen'd code.  Also could be applicable to a framework API where a specific implementation is required.  There's a couple rules around it.  1.  Your method must return void.  2.  Your method cannot contain any out arguments.

Automatic Properties

This one is just a flat out great LOC saver.  No more declaring member variables for your simple properties.  The below code is a perfectly legal form for a concrete property in C# 3.0;

public string Message { get; set;}

Extension Methods

I'm sure you've heard a ton about this one.  It's such a smart feature.  It allows you to slap your own method onto any class, just by including your namespace.  Below is an example of my extension method.  You can see the argument signature is a bit different.

public static class ExtensionMethods
{
    public static string CleanBRTags(this String theString)
    {
        return theString.Replace(@"<br \>", "");
    }
}

And here is the usage:

string myString = @"This is a test<br \>Line 2";
Console.WriteLine(myString.CleanBRTags());

Note that you must add your namespace to the calling class with a "using" statement, and your extension method must be static, as well as the class that holds the method.

Object Initializers

Another great LOC optimization.  What object initializers allow you to do is instantiate an object and initialize the parameters at the same time.  Take the below class:

public class MyObject
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

In C# 2.0, you would likely instantiate and hydrate this class like so:

MyObject myObject = new MyObject();
myObject.ID = 1;
myObject.FirstName = "Jim";
myObject.LastName = "Fiorato";

In C# 3.0, you can now do the following:

MyObject myObject = new MyObject() { ID = 1, FirstName = "Jim", LastName = "Fiorato" };

System.TimeZoneInfo Class

This one is the lone framework feature in this list.  Worthy of changing the entire title of this blog post (if I had just left it "My Top 5 Favorite New C# 3.0 Features", flaming comments, ridicule, and a sure end to my career would have followed).

Why do I love this one so much?  Because it's going to save me about 1,000 lines of code, an xml manifest with all the time zones in it, and I'll never ever have to patch every single released version of my application again.

First, you'll get all the time zones in the system.

foreach(TimeZoneInfo info in TimeZoneInfo.GetSystemTimeZones())
{
    Console.WriteLine(info.DisplayName);
}

Second, along with those time zones, you can get the offset from GMT and present a perfectly adjusted time zone to all your users across the globe.

DateTime currentTimeUtc = DateTime.Now.ToUniversalTime();
 
TimeZoneInfo myCurrentTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
 
DateTime myCurrentTime =
    TimeZoneInfo.ConvertTimeFromUtc(currentTimeUtc, myCurrentTimeZone);
 
Console.WriteLine("My Current Time is: {0}", myCurrentTime.ToString());

 

References

C# 3.0: Partial Methods - Wriju's Blog
New "Orcas" Language Feature: Extension Methods - Scott Guthrie's Blog