C# 3.0 - Magic and mechanics
C# 3.0 is Right Around the Corner (in the Microsoft sense of the word…), and it brings to bear a lot of interesting features. Most of them come together in the technology called LINQ (Language INtegrated Queries). Even though I doubt I will use C#, I think there is a lot that can be learned from this preview release. Let’s take a look at an example Query:
var contacts =
from cust in customers
where cust.State == "PA"
select new { cust.Name, cust.Email };
If the syntax looks familiar, that’s not strange. It’s modeled after SQL-syntax. As a matter of fact, if “customers” is a database table mapped with DLinq, the result will be a SQL call directly in the database! However, if customer is a collection or an XML file, LINQ will do The Right Thing. How can this work? In a word: Mechanics. The syntax as you see it is merely syntactic sugar for the following:
var contacts =
customers
.Where(cust => cust.State == "PA")
.Select(cust => new { Name = cust.Name, Email = cust.Email });
This is still pretty magical, but if we look at a few other new features, it will all be clear. First: “x => x.State == “PA” is a lambda expression with “x” as the lambda variable. As customer can be a generic collection, the compiler can presumably resolve the type of x statically. “new { Name = cust.Name, Email = cust.Email }” creates an anonymous class with two variables Name and Email. Last, “var” is a dynamically (or quasi-dynamically) typed variable. Presumably, it will be statically typed when the compiler can guess the type. In this case, it will be a collection of the anonymous class created by the select statements. These “implicitly typed” variables are essensial for dealing with anonymous classes. How else would you be able to say result[0].Name?
So much for the mechanical part. This first level of LINQ-translation is just syntactic sugar, and when you look at the resulting statement, it doesn’t even add all that much sweetness! I would instinctively prefer the later syntax. Of course, this syntax has an essential feature that is presently lacking from both C# and Java: lambdas. Now for the magic part:
I have been assured that these expression (“table.Where(row => row.Column1 == “Test”).Select(row => new { row.Column2, row.Column2 }”) will be translated into SQL when executed to the database. Presumably something like “SELECT column2, column3 FROM table WHERE column1 = ‘Test’”. Now here is what I want to know: Short of decompiling the lambda “row => row.Column1 == “Test””, how is that even possible!?
In conclusion: Integrating queries into the language is something that I don’t particuarly think is a good idea. It seems to be cluttering up the language a lot. Integrating lambda expressions and a good set of collection libraries that take advantage of them is, on the other hand, an obvious improvement. If I could just figure out how they translate those lambdas into SQL… Hmm… good stuff to think about.