tags:

views:

87

answers:

3

What is the reason for changing the order of these operators by Microsoft? Microsoft don't use select-from-where and change this order to from-where-select. Why? Is it only for better intellisense in VS?

+6  A: 

Not only does it allow for better Intellisense, but it properly mirrors the actual order of operations. For example, from e in Employees where e.Age > 65 select e.Salary would be rewritten as Employees.Where(e => e.Age > 65).Select(e => e.Salary).

It wouldn't make sense to write Select(e => e.Salary).Employees.Where(e => e.Age > 65).

Gabe
+5  A: 

LINQ is not only for database related operations, but for general querying and projection of in-memory data as well. Also consider the lambda expressions and extension methods that LINQ query expression syntax is syntactic sugar for.

var query = from foo in foos
            where foo.Bar == "Blah"
            select foo.Id;

Is syntactic sugar for

var query = foos.Where(foo => foo.Bar == "Blah").Select(foo => foo.Id);

The existing query expression syntax is close to lambda/extension syntax, and one of the first things the compiler does is translate the former to the latter, anyway. It's more descriptive of the order of things actually happening, as well.

Anthony Pegram
+5  A: 

As others have mentioned, it makes IntelliSense possible and it makes the query read in the same order that the operations are actually done: first you get the collection, then you filter it, then you project the filtered results.

A third reason is that this order makes the scoping rules more rational. You'll notice that in C#, you never introduce a new scope that "flows to the left". In SQL the stuff that is brought into scope by the FROM is used to the left of the FROM. In the C# syntax the range variables have to be used explicitly, so they have to be declared to the left of the code that uses them; the range variables are then in scope in various parts of the query.

One oddity in the scoping rules is the join clause. When you say

from c in customers
join o in orders on c.Id equals o.CustomerId

...

the range variable c is in scope between the on and the equals but o is not. Scope still flows to the right, but it can skip a subclause here and there in some cases.

Eric Lippert