"Keep the elements that pass a test, then transform the survivors" is one of the most common patterns in all of programming: pick the even numbers and square them, take the finished orders and grab their totals, and so on. You already know how to write it with a loop:
var evenSquares = new List<int>();
foreach (var x in nums) {
if (x % 2 == 0) {
evenSquares.Add(x * x);
}
}
C# ships a second way to say the same thing: LINQ (Language Integrated Query). Two of its methods cover this exact pattern:
Where(test)— keeps only the elements for which the test returnstrue(that's theif)Select(transform)— applies a transformation to every element that got through (that's thex * x)
Lambdas and chaining:
The test and the transform are written as lambdas — tiny inline functions. x => x % 2 == 0 reads as "given x, is x even?". The calls chain left to right, and .ToList() at the end turns the result back into a List<int>:
var evenSquares = nums.Where(x => x % 2 == 0).Select(x => x * x).ToList();
One line — same result as the five-line loop. Good to know: Where and Select are lazy. On their own they only describe the query; nothing actually runs until something enumerates it — and ToList() is what forces that to happen here.
The trap:
Where and Select are not methods of List<int>. They are extension methods that only come into scope while using System.Linq; sits at the top of your file. Delete that line and the compiler acts as if LINQ never existed:
error CS1061: 'List<int>' does not contain a definition for 'Where' and no accessible extension method 'Where' accepting a first argument of type 'List<int>' could be found (are you missing a using directive or an assembly reference?)
Read the part in parentheses — "are you missing a using directive" is the compiler telling you exactly what to fix. In this exercise using System.Linq; is already included for you, but the day you start a file from scratch, this is the error you will meet.
Assignment
Follow the Coding Tutorial and build both versions side by side. Start from var nums = new List<int> { 1, 2, 3, 4, 5, 6 };, then
- filter the evens and square them with a
foreachloop, collecting intoloopSquares, and print it, - do the same in one line with
Where+SelectintolinqSquares, and print it.
Print each list with string.Join(", ", ...). The exact expected output is:
loop: 4, 16, 36
linq: 4, 16, 36
Hint
The lambda inside Where must produce a bool (x => x % 2 == 0), while the one inside Select produces the new value (x => x * x). Finish the chain with .ToList() so the result is a real list you can print.
Free plan: 30 tutor messages. PRO is unlimited.
