Linq and C# 3.0

Yesterday, the C# team (among others) announced Linq and C# 3.0, and put up a great page of information. I haven't had a chance to look at things in detail to see how much they've changed since the last time I saw them in detail (about this time last year), but I do have a few things I'd like to comment on.

On first look, Linq looks great. I'm really happy at what you'll be able to do, and I think the language changes aren't too intrusive. Having spent some time recently writing a bunch of tedious DB stuff for a side project, Linq will really make things easier.

On the language side, there are a few cool enhancements.

The first is implicitly typed variables. This seems a bit out of place in a language like C#, but perhaps an example will better demonstrate why they're there. This is one of the Linq examples:

    List products = GetProductList();

    var productInfos =
        from p in products
        select new {p.ProductName, p.Category, Price = p.UnitPrice};

In this example, we're trying to select out 3 columns from the products table. The problem we have is that productInfos will end up being a List<X>, but there's no name for X - it's a compiler-generated type that has the three columns as members. One option is to require somebody to define a type with fields ProductName, Category, and Price in it, but that's tedious busywork at best. A second option is to require the user to name the type at some point in the "from" clause. After a fair bit of discussion, the design team decided that the best option was to add a "var" construct, where you can declare an instance of a variable without specifying a type name in it.

The use of "var" is not limited to Linq queries.

The second addition is something known as an extension method. Say that you're writing a new web-based game, and you need a way to convert from standard English to Leet Speak. You would like to be able to add a method to the string class, but because String is sealed (for some very good reasons), you can't. What you end up doing is writing a static method and calling it, but it's not very seamless.

With extension methods, you can write the following:

public static class StringExtensions
{
    public static string MakeLeet(this string source)
   {
      // return the Leet string here...
   }
}

You then write:

string s = "I have found the programming features of C# 3.0 to be most envigorating";
string leet = s.MakeLeet();
Console.WriteLine(leet);

and you get the following as output:

y0 d00d, C# 3.0 rox0rz, w00t!!!!!!!!!!!!

The other additions - lambda expressions et al are there to support the linq work, and I know enough not to try to cover something like Lambda expressions in a short note. (or perhaps even a long note). But if you're a master of the BNF, take a look at this.