LINQ коротко — Where, Select, OrderBy, Sum
LINQ (Language Integrated Query) — набор методов для работы с массивами, списками и другими наборами данных: отобрать, преобразовать, отсортировать, посчитать. Вместо цикла на десяток строк — одна строка:
int[] numbers = { 5, 3, 8, 1, 9, 2 };
var even = numbers.Where(n => n % 2 == 0);
Console.WriteLine(string.Join(" ", even));
var squares = numbers.Select(n => n * n);
Console.WriteLine(string.Join(" ", squares));
var sorted = numbers.OrderBy(n => n);
Console.WriteLine(string.Join(" ", sorted));
Console.WriteLine(numbers.Sum());
Console.WriteLine(numbers.Max());
Console.WriteLine(numbers.Count(n => n > 4));
Console.WriteLine(numbers.Any(n => n > 100));8 2
25 9 64 1 81 4
1 2 3 5 8 9
28
9
3
FalseМетоды LINQ лежат в System.Linq, в проектах .NET 6 и новее он подключён сам.
Что значит n => n % 2 == 0
Это лямбда-выражение — короткая безымянная функция: «для элемента n вернуть n % 2 == 0». Where вызывает её для каждого элемента и оставляет те, для которых она вернула true. Select берёт результат лямбды вместо элемента. Имя n может быть любым.
Главные методы
| Метод | Что делает |
|---|---|
Where(x => условие) | оставить подходящие |
Select(x => выражение) | преобразовать каждый элемент |
OrderBy(x => ключ), OrderByDescending(...) | сортировать по возрастанию, по убыванию |
ThenBy(x => ключ) | дополнительная сортировка при равных ключах |
Sum(), Max(), Min(), Average() | сумма, максимум, минимум, среднее |
Count(), Count(x => условие) | сколько всего, сколько подходящих |
Any(x => условие), All(x => условие) | есть ли хоть один подходящий, все ли подходят |
First(...), FirstOrDefault(...) | первый подходящий; второй вернёт значение по умолчанию, если таких нет |
Distinct() | без повторов |
ToList(), ToArray() | собрать результат в список или массив |
Пример со своими объектами
var students = new List<Student>
{
new Student("Анна", 9),
new Student("Борис", 7),
new Student("Вера", 10),
new Student("Глеб", 7)
};
var best = students.Where(s => s.Mark >= 9).Select(s => s.Name);
Console.WriteLine(string.Join(", ", best));
var ordered = students.OrderByDescending(s => s.Mark).ThenBy(s => s.Name);
foreach (var s in ordered)
{
Console.WriteLine($"{s.Name}: {s.Mark}");
}
Student? first = students.FirstOrDefault(s => s.Mark == 7);
Console.WriteLine(first?.Name);
record Student(string Name, int Mark);Анна, Вера
Вера: 10
Анна: 9
Борис: 7
Глеб: 7
Борисrecord Student(string Name, int Mark); — короткая запись класса с двумя свойствами и конструктором. Методы можно соединять в цепочку: Where отбирает, Select берёт из каждого ученика только имя. Запись first?.Name даёт имя, а если first равно null — просто null, без ошибки.
Подводные камни
- Отложенное выполнение.
Where,Select,OrderByничего не считают сразу, а только описывают запрос: он выполняется, когда результат перебирают (foreach,string.Join,ToList). Если исходный список потом изменится, повторный перебор даст уже другой результат. Чтобы «заморозить» его, вызовитеToList(). First()бросает исключениеInvalidOperationException, если подходящих нет, аMax()иAverage()— если набор пуст. Для «может не найтись» беритеFirstOrDefault()и проверяйте результат наnull.OrderByне меняет исходный массив, а возвращает новый порядок. Отсортировать сам массив —Array.Sort, сам список —list.Sort().- Есть и вторая запись LINQ, похожая на SQL (язык запросов к базам данных):
from n in numbers where n > 3 select n— делает то же, чтоnumbers.Where(n => n > 3).