WHERE и фильтрация
Выбирайте подходящие элементы
«WHERE и фильтрация» — бесплатный урок C# Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.
Что делает Where
Where — основной оператор фильтрации LINQ. Он принимает предикат — функцию, возвращающую bool, — и выдаёт только элементы, которые ему соответствуют.
Он определён в System.Linq и работает с любым IEnumerable<T>, возвращая новую последовательность, а не изменяя исходную.
using System;
using System.Linq;
using System.Collections.Generic;
var nums = new List<int> { 1, 2, 3, 4, 5, 6 };
var evens = nums.Where(n => n % 2 == 0);
Console.WriteLine(string.Join(", ", evens));Лямбда-выражение предиката
Аргументом Where является лямбда-выражение n => condition. Параметр представляет каждый элемент, а тело должно вычисляться в значение true или false.
Возврат true сохраняет элемент, а false отбрасывает его. Подходит любое логическое выражение.
using System;
using System.Linq;
string[] words = { "apple", "fig", "banana", "kiwi" };
var shortWords = words.Where(w => w.Length <= 4);
Console.WriteLine(string.Join(", ", shortWords));Вариант синтаксиса запросов
LINQ предлагает синтаксис запросов, похожий на SQL. Предложение where выполняет фильтрацию, а select — проекцию.
Он компилируется в те же вызовы методов, поэтому from x in src where ... select x эквивалентно src.Where(...). Используйте тот вариант, который читается понятнее.
using System;
using System.Linq;
int[] scores = { 40, 75, 90, 55, 88 };
var passing = from s in scores
where s >= 60
select s;
Console.WriteLine(string.Join(", ", passing));Объединение условий
Внутри одного предиката можно объединить несколько проверок с помощью && и ||. Так связанные условия фильтрации проверяются за один проход.
Скобки повышают читаемость при смешивании операторов, как и в любом логическом выражении.
using System;
using System.Linq;
using System.Collections.Generic;
var ages = new List<int> { 12, 17, 21, 35, 64, 70 };
var adults = ages.Where(a => a >= 18 && a < 65);
Console.WriteLine(string.Join(", ", adults));Цепочка вызовов Where
Можно объединять несколько вызовов Where в цепочку. Каждый из них фильтрует результат предыдущего, поэтому условия объединяются с помощью логического AND.
Цепочка иногда понятнее одного большого предиката и позволяет составлять фильтры, созданные в разных местах.
using System;
using System.Linq;
int[] data = { 3, 8, 15, 22, 27, 40 };
var result = data.Where(n => n > 5)
.Where(n => n % 2 == 0);
Console.WriteLine(string.Join(", ", result));Where с индексом
Одна из перегрузок Where предоставляет индекс элемента, отсчитываемый от нуля, как второй параметр лямбда-выражения. Это удобно для фильтрации по позиции.
Используйте её, например, чтобы сохранять каждый второй элемент или пропускать первый элемент по индексу.
using System;
using System.Linq;
string[] items = { "a", "b", "c", "d", "e" };
var evenIdx = items.Where((val, idx) => idx % 2 == 0);
Console.WriteLine(string.Join(", ", evenIdx));Фильтрация объектов
Фильтрация особенно полезна для коллекций объектов. Предикат может обращаться к любому свойству каждого элемента.
Так декларативно формулируются бизнес-правила: «клиенты из этого города», «заказы выше порогового значения».
using System;
using System.Linq;
using System.Collections.Generic;
record Product(string Name, decimal Price);
var list = new List<Product> {
new("Pen", 1.5m), new("Lamp", 20m), new("Mug", 8m) };
var cheap = list.Where(p => p.Price < 10);
foreach (var p in cheap) Console.WriteLine(p.Name);Отложенное выполнение
Where использует отложенное выполнение: он запускается не при создании, а только при переборе последовательности, например в foreach или при вызове ToList.
Это означает, что изменения исходной последовательности до перебора отражаются в результате.
using System;
using System.Linq;
using System.Collections.Generic;
var src = new List<int> { 1, 2 };
var q = src.Where(n => n > 1);
src.Add(5);
Console.WriteLine(string.Join(", ", q));Стоимость повторной проверки
Поскольку фильтрация выполняется отложенно, повторный перебор одного и того же запроса дважды запускает предикат. Для дорогих предикатов или изменяющихся источников это может стать неожиданностью.
Если нужен стабильный снимок, который можно использовать повторно, один раз материализуйте результат с помощью ToList — мы рассмотрим это позже в курсе.
using System;
using System.Linq;
int calls = 0;
int[] nums = { 1, 2, 3 };
var q = nums.Where(n => { calls++; return n > 1; });
foreach (var _ in q) { }
foreach (var _ in q) { }
Console.WriteLine(calls);Сначала фильтрация, затем подсчёт
Распространённый шаблон — отфильтровать элементы, а затем узнать, сколько из них подошло. Count может напрямую принимать предикат, объединяя фильтрацию и подсчёт.
count.Count(p => cond) эквивалентно seq.Where(p => cond).Count(), но записывается компактнее.
using System;
using System.Linq;
int[] grades = { 55, 80, 42, 91, 67 };
int passed = grades.Count(g => g >= 60);
Console.WriteLine($"Passed: {passed}");Пустые результаты — это нормально
Если ни один элемент не удовлетворяет предикату, Where просто выдаёт пустую последовательность — никогда не null.
Благодаря этому фильтры безопасно объединять в цепочку: пустой результат передаётся последующим операторам без специальной обработки.
using System;
using System.Linq;
int[] nums = { 1, 2, 3 };
var big = nums.Where(n => n > 100);
Console.WriteLine($"Count: {big.Count()}");Быстрая проверка
Проверьте, насколько Вы поняли отложенное выполнение.
Итоги
Where фильтрует последовательность с помощью логического предиката, возвращая новый IEnumerable. У него есть перегрузка с индексом; вызовы можно объединять в цепочку или сочетать с &&/||, а с объектами оператор работает через их свойства.
Важно, что выполнение отложено: оператор запускается при переборе, поэтому повторный перебор повторно вычисляет предикат. Далее с помощью Select мы сформируем нужную структуру данных.
Часто задаваемые вопросы
Урок «WHERE и фильтрация» бесплатный?
Да — полный текст урока «WHERE и фильтрация» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.
Чему я научусь в уроке «WHERE и фильтрация»?
Выбирайте подходящие элементы Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C# Academy?
Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «WHERE и фильтрация»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C# Academy?
Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- WHERE и фильтрация
- SELECT и проекция
- OrderBy и группировка
- Агрегаты и ToList