- Read and write a lambda expression (
x => ...) - Filter, transform and sort a collection with
Where,SelectandOrderBy - Summarise results with
Sum,Average,Count,AnyandGroupBy - Explain deferred execution and the role of
ToList()
You need to find the students in a class list who scored above 80, sort them from highest to lowest and take only their names. With loops that means new lists, if statements and sorting code. With LINQ (Language Integrated Query), the same job takes a few readable lines — as if you were simply telling the computer what you want.
Lambda expressions
A short function without a name: the parameter goes to the left of the arrow (=>) and the result to the right. n => n * 2 means “take n, return n · 2”, and s => s.Score >= 80 answers the question “is the student's score 80 or more?” with true/false.
LINQ methods work with any collection — an array, a List<T>, a dictionary — and take a lambda as an argument. They do not change the original collection but return a new result. In the example below, Where picks the elements that match a condition, Select transforms every element and OrderBy sorts them.
int[] numbers = [5, 12, 8, 3, 20, 7];
var evens = numbers.Where(n => n % 2 == 0);
var doubled = numbers.Select(n => n * 2);
var sorted = numbers.OrderBy(n => n);
Console.WriteLine(string.Join(", ", evens));
Console.WriteLine(string.Join(", ", doubled));
Console.WriteLine(string.Join(", ", sorted));
Console.WriteLine($"Sum: {numbers.Sum()}, max: {numbers.Max()}");
Console.WriteLine($"Greater than 6: {numbers.Count(n => n > 6)}");12, 8, 20 10, 24, 16, 6, 40, 14 3, 5, 7, 8, 12, 20 Sum: 55, max: 20 Greater than 6: 4
Chaining methods
Because every LINQ method returns a new sequence, you can call the next method on it straight away. Such a chain reads from top to bottom like a sentence: “pick those with 80 or more, sort them by score from highest, take their names”. Chains are usually written with each method on its own line.
using System.Globalization;
CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
List<Student> students =
[
new("Aysel", 95), new("Murad", 78), new("Leyla", 88),
new("Elvin", 45), new("Nigar", 91)
];
var topNames = students
.Where(s => s.Score >= 80)
.OrderByDescending(s => s.Score)
.Select(s => s.Name);
Console.WriteLine(string.Join(", ", topNames));
Console.WriteLine($"Average: {students.Average(s => s.Score):F1}");
Console.WriteLine($"Everyone passed: {students.All(s => s.Score >= 50)}");
Console.WriteLine($"Anyone above 90: {students.Any(s => s.Score > 90)}");
Console.WriteLine($"Best: {students.OrderByDescending(s => s.Score).First().Name}");
record Student(string Name, int Score);Aysel, Nigar, Leyla Average: 79.4 Everyone passed: False Anyone above 90: True Best: Aysel
| Method | What it does |
|---|---|
Where(x => ...) | keeps the elements that match the condition |
Select(x => ...) | turns every element into another value |
OrderBy / OrderByDescending | sorts in ascending / descending order |
Sum, Average, Min, Max, Count | total, average, smallest, largest, number of items |
First / FirstOrDefault | gives the first element; if empty — an error / null |
Any / All | does at least one / every element match |
GroupBy(x => ...) | groups the elements by a key |
ToList() | turns the result into a ready list |
Grouping
GroupBy splits elements into groups by a shared key: for example, products by category. Each group has a Key property, and the group itself is a collection, so you can call Count and Sum on it. FirstOrDefault does not throw an error when nothing matches — it returns null.
List<Product> products =
[
new("Laptop", "Electronics", 1500),
new("Pen", "Stationery", 2),
new("Phone", "Electronics", 900),
new("Notebook", "Stationery", 5),
new("Mouse", "Accessories", 25)
];
var groups = products
.GroupBy(p => p.Category)
.OrderBy(g => g.Key);
foreach (var g in groups)
Console.WriteLine($"{g.Key}: {g.Count()} item(s), total {g.Sum(p => p.Price)} AZN");
Product? cheap = products.FirstOrDefault(p => p.Price < 1);
Console.WriteLine(cheap is null ? "No product under 1 AZN" : cheap.Name);
record Product(string Name, string Category, decimal Price);Accessories: 1 item(s), total 25 AZN Electronics: 2 item(s), total 2400 AZN Stationery: 2 item(s), total 7 AZN No product under 1 AZN
Product? says the variable may be null.OrderBy saves you from writing a sorting algorithm yourself. Here you can watch one of the simple algorithms work step by step.Deferred execution
When you call Where and Select, nothing is calculated yet — only the “recipe” is stored. The query runs when you actually ask for the result: in foreach, in string.Join or in methods like Sum. This is called deferred execution. To “freeze” the result at that moment, call ToList().
List<int> scores = [50, 70, 90];
var high = scores.Where(s => s > 60);
var snapshot = scores.Where(s => s > 60).ToList();
scores.Add(100);
Console.WriteLine(string.Join(", ", high));
Console.WriteLine(string.Join(", ", snapshot));70, 90, 100 70, 90
high query ran after 100 was added, while snapshot had been built beforehand.Key points
- A lambda is a short nameless function:
n => n * 2. Wherefilters,Selecttransforms,OrderBy/OrderByDescendingsort.Sum,Average,Max,Count,AnyandAllproduce one answer from a whole collection.- LINQ does not change the original collection; methods can be chained.
- A query runs when the result is requested;
ToList()builds the result immediately.
Check yourself
10 questions. Every correct answer earns XP.
int[] a = [1, 2, 3, 4];, what is a.Where(n => n > 2).Sum()?