Whether I use expression query syntax or method syntax the IL looks virtually the same.
Doing the LINQ query as 'progressive syntax':
IEnumerable<Employee> query1 = _employees.Where(e => e.Location.Equals("California"));
IEnumerable<Employee> query2 = query1.OrderByDescending(e => e.Name);
IEnumerable<string> query3 = query2.Select(e => e.Name);
generates:
IL_0001: ldarg.0 // this
IL_0002: ldfld class [mscorlib]System.Collections.Generic.IList`1<class Fundamentals.LINQ.Employee> Fundamentals.LINQ.Syntax::_employees
IL_0007: ldsfld class [mscorlib]System.Func`2<class Fundamentals.LINQ.Employee, bool> Fundamentals.LINQ.Syntax/'<>c'::'<>9__3_0'
IL_000c: dup
IL_000d: brtrue.s IL_0026
IL_000f: pop
IL_0010: ldsfld class Fundamentals.LINQ.Syntax/'<>c' Fundamentals.LINQ.Syntax/'<>c'::'<>9'
IL_0015: ldftn instance bool Fundamentals.LINQ.Syntax/'<>c'::'<TestMethodSyntaxProgressive>b__3_0'(class Fundamentals.LINQ.Employee)
IL_001b: newobj instance void class [mscorlib]System.Func`2<class Fundamentals.LINQ.Employee, bool>::.ctor(object, native int)
IL_0020: dup
IL_0021: stsfld class [mscorlib]System.Func`2<class Fundamentals.LINQ.Employee, bool> Fundamentals.LINQ.Syntax/'<>c'::'<>9__3_0'
IL_0026: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0/*class Fundamentals.LINQ.Employee*/> [System.Core]System.Linq.Enumerable::Where<class Fundamentals.LINQ.Employee>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0/*class Fundamentals.LINQ.Employee*/>, class [mscorlib]System.Func`2<!!0/*class Fundamentals.LINQ.Employee*/, bool>)
IL_002b: stloc.0 // query1
// [100 13 - 100 82]
IL_002c: ldloc.0 // query1
IL_002d: ldsfld class [mscorlib]System.Func`2<class Fundamentals.LINQ.Employee, string> Fundamentals.LINQ.Syntax/'<>c'::'<>9__3_1'
IL_0032: dup
IL_0033: brtrue.s IL_004c
IL_0035: pop
IL_0036: ldsfld class Fundamentals.LINQ.Syntax/'<>c' Fundamentals.LINQ.Syntax/'<>c'::'<>9'
IL_003b: ldftn instance string Fundamentals.LINQ.Syntax/'<>c'::'<TestMethodSyntaxProgressive>b__3_1'(class Fundamentals.LINQ.Employee)
IL_0041: newobj instance void class [mscorlib]System.Func`2<class Fundamentals.LINQ.Employee, string>::.ctor(object, native int)
IL_0046: dup
IL_0047: stsfld class [mscorlib]System.Func`2<class Fundamentals.LINQ.Employee, string> Fundamentals.LINQ.Syntax/'<>c'::'<>9__3_1'
IL_004c: call class [System.Core]System.Linq.IOrderedEnumerable`1<!!0/*class Fundamentals.LINQ.Employee*/> [System.Core]System.Linq.Enumerable::OrderByDescending<class Fundamentals.LINQ.Employee, string>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0/*class Fundamentals.LINQ.Employee*/>, class [mscorlib]System.Func`2<!!0/*class Fundamentals.LINQ.Employee*/, !!1/*string*/>)
IL_0051: stloc.1 // query2
// [101 13 - 101 69]
IL_0052: ldloc.1 // query2
IL_0053: ldsfld class [mscorlib]System.Func`2<class Fundamentals.LINQ.Employee, string> Fundamentals.LINQ.Syntax/'<>c'::'<>9__3_2'
IL_0058: dup
IL_0059: brtrue.s IL_0072
IL_005b: pop
IL_005c: ldsfld class Fundamentals.LINQ.Syntax/'<>c' Fundamentals.LINQ.Syntax/'<>c'::'<>9'
IL_0061: ldftn instance string Fundamentals.LINQ.Syntax/'<>c'::'<TestMethodSyntaxProgressive>b__3_2'(class Fundamentals.LINQ.Employee)
IL_0067: newobj instance void class [mscorlib]System.Func`2<class Fundamentals.LINQ.Employee, string>::.ctor(object, native int)
IL_006c: dup
IL_006d: stsfld class [mscorlib]System.Func`2<class Fundamentals.LINQ.Employee, string> Fundamentals.LINQ.Syntax/'<>c'::'<>9__3_2'
IL_0072: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!1/*string*/> [System.Core]System.Linq.Enumerable::Select<class Fundamentals.LINQ.Employee, string>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0/*class Fundamentals.LINQ.Employee*/>, class [mscorlib]System.Func`2<!!0/*class Fundamentals.LINQ.Employee*/, !!1/*string*/>)
IL_0077: stloc.2 // query3
According to the way LINQ works is that the output sequence from the Where() operation should become the input sequence to OrderByDescending(), and the 2nd output sequence should flow into the Select(). I just can't understand which IL codes correspond to that.
Is this the magic part?
IL_002b: stloc.0 // query1
// [100 13 - 100 82]
IL_002c: ldloc.0 // query1
If I do the LINQ query as 'fluent':
IEnumerable<string> names = _employees.Where(e => e.Location.Equals("California")).OrderByDescending(e => e.Name).Select(e => e.Name);
I do not get the stloc.0, ldloc.0 instructions. That's the only difference in the IL emitted between 'progressive syntax' & 'fluent syntax'. Is there a second step in the JIT-compiler that generates extra IL instructions that do the sequence inputting?