2010年12月14日星期二

LINQ Query Syntax versus Method Syntax (C#)

At compile time, query expressions are translated to something that the CLR does understand: method calls.
These methods are called the standard query operators, and they have names such as Where, Select, GroupBy, Join, Max, Average, and so on. You can call them directly by using method syntax instead of query syntax.

The following example shows a simple query expression and the semantically equivalent query written as a method-based query.

class QueryVMethodSyntax
{
    static void Main()
    {
        int[] numbers = { 5, 10, 8, 3, 6, 12};
        //Query syntax:
        IEnumerable<int> numQuery1 =
            from num in numbers
            where num % 2 == 0
            orderby num
            select num;
        //Method syntax:
        IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);
        foreach (int i in numQuery1)
        {
            Console.Write(i + " ");
        }
        Console.WriteLine(System.Environment.NewLine);
        foreach (int i in numQuery2)
        {
            Console.Write(i + " ");
        }
        // Keep the console open in debug mode.
        Console.WriteLine(System.Environment.NewLine);
        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}
/*
    Output:
    6 8 10 12
    6 8 10 12
 */

The output from the two examples is identical. You can see that the type of the query variable is the same in both forms: IEnumerable<T>.
If you are familiar with the generic IEnumerable<T> interface, you know that it does not have a Where method. However, if you invoke the IntelliSense completion list in the Visual Studio IDE, you will see not only a Where method, but many other methods such as Select, SelectMany, Join, and Orderby. These are all the standard query operators.

Although it looks as if IEnumerable<T> has been redefined to include these additional methods, in fact this is not the case. The standard query operators are implemented as a new kind of method called extension methods. Extensions methods "extend" an existing type; they can be called as if they were instance methods on the type. The standard query operators extend IEnumerable<T> and that is why you can write numbers.Where(...).

没有评论: