← Назад к вопросам

В чём разница между Select и Where?

1.0 Junior🔥 271 комментариев
#Коллекции и структуры данных

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между Select и Where в LINQ (C#)

Основное отличие между Select и Where заключается в их предназначении: Where используется для фильтрации коллекции по определённому условию, а Select — для проекции (преобразования) каждого элемента коллекции в новую форму. Оба метода являются частью LINQ (Language Integrated Query) и реализуют отложенное выполнение (deferred execution).

Ключевые различия

АспектWhereSelect
НазначениеФильтрация элементов, удовлетворяющих условиюПреобразование (проекция) каждого элемента
Возвращаемый типКоллекция того же типа IEnumerable<T>Коллекция нового типа IEnumerable<TResult>
Лямбда-выражениеДолжно возвращать bool (условие фильтрации)Может возвращать любой тип (результат преобразования)
Влияние на количество элементовМожет уменьшить количество элементов (или оставить тем же)Сохраняет количество элементов, изменяя их содержание

Примеры использования

Метод Where (фильтрация)

using System;
using System.Linq;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
        
        // Фильтруем только чётные числа
        var evenNumbers = numbers.Where(n => n % 2 == 0);
        
        foreach (var num in evenNumbers)
        {
            Console.WriteLine(num); // Вывод: 2, 4, 6
        }
        
        // Более сложный пример с объектами
        var persons = new List<Person>
        {
            new Person { Name = "Анна", Age = 25 },
            new Person { Name = "Иван", Age = 30 },
            new Person { Name = "Мария", Age = 20 }
        };
        
        var adults = persons.Where(p => p.Age >= 18);
        // persons остаётся неизменной, adults содержит все три объекта
    }
}

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Метод Select (проекция)

using System;
using System.Linq;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var numbers = new List<int> { 1, 2, 3, 4, 5 };
        
        // Преобразуем числа в их квадраты
        var squares = numbers.Select(n => n * n);
        
        foreach (var square in squares)
        {
            Console.WriteLine(square); // Вывод: 1, 4, 9, 16, 25
        }
        
        // Проекция в другой тип
        var persons = new List<Person>
        {
            new Person { Name = "Анна", Age = 25 },
            new Person { Name = "Иван", Age = 30 }
        };
        
        // Преобразуем Person в строку
        var names = persons.Select(p => p.Name);
        // names содержит "Анна", "Иван" (тип IEnumerable<string>)
        
        // Создание анонимных типов
        var personInfo = persons.Select(p => new 
        { 
            p.Name, 
            IsAdult = p.Age >= 18 
        });
    }
}

Комбинирование методов

Where и Select часто используются вместе в цепочке вызовов:

var result = numbers
    .Where(n => n > 2)          // Сначала фильтруем: 3, 4, 5
    .Select(n => n * 10)        // Затем преобразуем: 30, 40, 50
    .ToList();

Важные особенности

Отложенное выполнение (Deferred Execution)

Оба метода используют отложенное выполнение — запрос не выполняется до тех пор, пока не будет начато перечисление результатов:

var query = numbers.Where(n => n > 3); // Запрос ещё не выполнен
var list = query.ToList();            // Выполнение происходит здесь

Исключения

  • Where: лямбда-выражение должно возвращать bool. Если условие возвращает не bool, возникнет ошибка компиляции.
  • Select: может возвращать любой тип, включая анонимные типы.

Производительность

  • Where пропускает элементы, не удовлетворяющие условию, что может сократить время выполнения последующих операций.
  • Select применяется ко всем элементам, полученным на предыдущем шаге цепочки.

Практическое применение

В реальных проектах:

  1. Where используется для:

    • Фильтрации данных по критериям (активные пользователи, завершённые заказы)
    • Поиска элементов в коллекции
    • Очистки данных от невалидных значений
  2. Select применяется для:

    • Преобразования объектов DTO в модели представления
    • Извлечения конкретных полей из объектов
    • Вычисления производных значений
    • Создания проекций для клиентской части приложения
// Типичный сценарий в веб-приложении
var userDtos = dbContext.Users
    .Where(u => u.IsActive && u.LastLogin > DateTime.Now.AddDays(-30))
    .Select(u => new UserViewModel
    {
        Id = u.Id,
        FullName = $"{u.LastName} {u.FirstName}",
        Email = u.Email,
        LoginCount = u.LoginHistory.Count
    })
    .ToList();

Заключение

Понимание различий между Select и Where критически важно для эффективной работы с LINQ. Проще всего запомнить:

  • Where — "оставить только те элементы, которые..." (фильтрация)
  • Select — "взять каждый элемент и преобразовать его в..." (проекция)

Эти методы являются фундаментальными строительными блоками LINQ и часто используются вместе для создания сложных, но читаемых запросов к данным.