end[0]72[1]45[2]90[3]61s => s >= 60Wheres => s + 5Select$ dotnet run7795661int[] scores = {72, 45, 90, 61};2var passed = scores3 .Where(s => s >= 60)4 .Select(s => s + 5);5foreach (var p in passed)6 Console.WriteLine(p);7List<int> list = passed.ToList();[0][1][2]1from s in scores2where s >= 603select s + 5;next?
Back row: the source, the Where and Select operators, the consoleFront row: the code, the List<int> from ToList, query syntaxTokens: the next? request, a score going down the chain, the new valueBack row: the array scores (72, 45, 90, 61), the Where machine with its lambda s => s >= 60, the Select machine with s => s + 5, and the console. Front row: the program, the List<int> that ToList fills, and the same query in query syntax. Building the query moves nothing. Each pull sends a request up the chain and brings one score down it; Where drops 45, Select adds 5, and the console prints 77, 95 and 66. ToList pulls everything through again. The figure shows Where and Select as two machines. For an array, the .NET library may merge Where followed by Select into one iterator object as an optimisation; your lambdas are still called in the same order, one item at a time.

LINQ and lambdas

  1. LINQ (Language-Integrated Query) is a set of methods, such as Where and Select, that query any sequence: an array, a List<T>, anything that is an IEnumerable<T>. You chain them into a pipeline: a source, some operators, then a loop that uses the results.

Deferred execution

Pulling items through

Another way to write it

What happens

// step 1/9 · linq
LINQ      Language-Integrated Query: methods in System.Linq
works on  any IEnumerable<T>: arrays, List<T>, ...
a query   source  →  operators (Where, Select, ...)  →  a loop
each operator takes a lambda that says what to do with one item

The figure shows Where and Select as two machines. For an array, the .NET library may merge Where followed by Select into one iterator object as an optimisation; your lambdas are still called in the same order, one item at a time. Where and Select are deferred and streaming: they read one item, act on it, and hand it on. A few operators, such as OrderBy, must read the whole source before they can hand out the first item. ToList, ToArray, Count and First run the query at once.