Какой тип объекта возвращает метод LINQ Where в C#?

«Какой тип объекта возвращает метод LINQ Where в C#?» — вопрос из категории C# Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Метод расширения Where возвращает объект, реализующий интерфейс IEnumerable<T> (при работе с коллекциями в памяти) или IQueryable<T> (при работе с LINQ-провайдерами, например, Entity Framework Core).

1. Для коллекций в памяти (LINQ to Objects):

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
IEnumerable<int> filteredEnumerable = numbers.Where(n => n > 2);
// Тип результата: IEnumerable<int>

Важно: Это отложенное выполнение (deferred execution). Запрос не выполняется до момента итерации (например, в foreach) или принудительной материализации.

2. Для запросов к базе данных (например, в EF Core):

IQueryable<Product> dbQuery = _context.Products;
IQueryable<Product> filteredQueryable = dbQuery.Where(p => p.Price > 100);
// Тип результата: IQueryable<Product>

IQueryable<T> представляет собой дерево выражений, которое транслируется провайдером (например, в SQL) и выполняется на стороне сервера базы данных. Выполнение также отложенное.

Материализация результатов: Чтобы немедленно выполнить запрос и получить коллекцию, нужно вызвать методы, такие как ToList(), ToArray(), ToDictionary().

List<int> materializedList = numbers.Where(n => n > 2).ToList();
// Запрос выполняется здесь, результат — List<int>

Итог: Where возвращает запрос (IEnumerable<T>/IQueryable<T>), а не готовую коллекцию. Это основа ленивых вычислений и эффективной работы с базами данных в LINQ.