- Читать и писать лямбда-выражения (
x => ...) - Фильтровать, преобразовывать и сортировать коллекцию с помощью
Where,SelectиOrderBy - Подводить итоги с помощью
Sum,Average,Count,AnyиGroupBy - Объяснять отложенное выполнение и роль
ToList()
Нужно найти в списке класса учеников, набравших больше 80 баллов, отсортировать их по убыванию и взять только имена. С циклами это новые списки, условия if и код сортировки. С LINQ (Language Integrated Query — встроенный в язык запрос) та же работа занимает несколько понятных строк — словно ты просто говоришь компьютеру, что тебе нужно.
Лямбда-выражения
Короткая безымянная функция: слева от стрелки (=>) — параметр, справа — результат. n => n * 2 означает «возьми n, верни n · 2», а s => s.Score >= 80 отвечает true/false на вопрос «набрал ли ученик 80 баллов или больше?».
Методы LINQ работают с любой коллекцией — массивом, List<T>, словарём — и принимают лямбду в качестве аргумента. Они не меняют исходную коллекцию, а возвращают новый результат. В примере ниже Where отбирает элементы, подходящие под условие, Select преобразует каждый элемент, а OrderBy сортирует.
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
Цепочки методов
Поскольку каждый метод LINQ возвращает новую последовательность, на ней можно сразу вызвать следующий метод. Такая цепочка читается сверху вниз как предложение: «отбери тех, у кого 80 и больше, отсортируй по убыванию баллов, возьми имена». Цепочки обычно пишут так, чтобы каждый метод был на отдельной строке.
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
| Метод | Что делает |
|---|---|
Where(x => ...) | отбирает элементы, подходящие под условие |
Select(x => ...) | превращает каждый элемент в другое значение |
OrderBy / OrderByDescending | сортирует по возрастанию / убыванию |
Sum, Average, Min, Max, Count | сумма, среднее, минимум, максимум, количество |
First / FirstOrDefault | даёт первый элемент; если пусто — ошибка / null |
Any / All | подходит ли хотя бы один / все элементы |
GroupBy(x => ...) | группирует элементы по ключу |
ToList() | превращает результат в готовый список |
Группировка
GroupBy делит элементы на группы по общему ключу: например, товары по категориям. У каждой группы есть свойство Key (ключ), а сама группа — тоже коллекция, поэтому у неё можно вызвать Count и Sum. А FirstOrDefault, если подходящего элемента нет, не выбрасывает ошибку, а возвращает 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? означает, что переменная может быть null.OrderBy избавляет от необходимости самому писать алгоритм сортировки. Здесь можно посмотреть, как шаг за шагом работает один из простых алгоритмов.Отложенное выполнение
При вызове Where и Select ещё ничего не вычисляется — запоминается только «рецепт». Запрос выполняется, когда результат действительно нужен: в foreach, в string.Join или в методах вроде Sum. Это называется отложенным выполнением. Чтобы «заморозить» результат в данный момент, вызови 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 выполнился уже после добавления 100, а snapshot был построен заранее.Главное
- Лямбда — короткая безымянная функция:
n => n * 2. Whereфильтрует,Selectпреобразует,OrderBy/OrderByDescendingсортируют.Sum,Average,Max,Count,AnyиAllдают один ответ по всей коллекции.- LINQ не меняет исходную коллекцию; методы можно соединять в цепочки.
- Запрос выполняется, когда запрашивают результат;
ToList()строит результат сразу.
Проверь себя
Вопросов: 10. Каждый правильный ответ приносит XP.
int[] a = [1, 2, 3, 4];. Чему равно a.Where(n => n > 2).Sum()?