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

В чём разница между IEnumerable и IQueryable?

2.3 Middle🔥 81 комментариев
#C# и ООП#Коллекции и структуры данных

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

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

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

Разница между IEnumerable и IQueryable в контексте Unity и C#

В Unity разработке, использующей C#, понимание различий между IEnumerable и IQueryable критически важно для эффективной работы с данными, особенно при интеграции с базами данных или при выполнении сложных фильтраций и проекций на больших объемах данных.

Основная концептуальная разница

IEnumerable представляет собой базовый интерфейс для всех коллекций в C#. Он предназначен для локальной обработки данных, уже находящихся в памяти (например, массивы, списки List<T>). Его методы, такие как Where, Select, выполняются непосредственно в памяти приложения.

IQueryable наследуется от IEnumerable, но добавляет возможность построения и выполнения запросов к внешнему источнику данных (например, к базе данных через LINQ to SQL или Entity Framework). Он представляет собой "описание запроса", которое может быть трансформировано в другой язык (например, SQL) и выполнено удаленно.

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

  1. Место выполнения запроса
    *   `IEnumerable`: Запрос выполняется **на клиенте** (в памяти Unity-приложения). Все данные сначала загружаются локально, затем фильтруются.
    *   `IQueryable`: Запрос выполняется **на сервере** (в источнике данных). На клиент передается только конечный результат.

  1. Механизм выполнения (Deferred Execution)
    Оба интерфейса поддерживают отложенное выполнение, но реализация отличается:

```csharp
// Пример с IEnumerable (Unity-контекст: фильтрация списка GameObject)
List<GameObject> allObjects = new List<GameObject>(FindObjectsOfType<GameObject>());
IEnumerable<GameObject> enumerableQuery = allObjects.Where(obj => obj.tag == "Enemy");
// Запрос выполняется HERE в памяти, перебирая весь 'allObjects'
foreach (var enemy in enumerableQuery) { /* ... */ }

// Пример с IQueryable (Контекст базы данных)
IQueryable<PlayerData> queryableQuery = dbContext.Players.Where(p => p.Level > 10);
// Запрос трансформируется в SQL "SELECT * FROM Players WHERE Level > 10"
// и выполняется на сервере базы данных. В память приложения попадут только записи Level > 10.
var result = queryableQuery.ToList();
```

3. Оптимизация и производительность

    Использование `IQueryable` для внешних источников данных **гораздо более эффективно**. Вы избегаете передачи всех данных в память приложения для последующей фильтрации.

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

В чистом Unity-проекте вы чаще всего будете работать с IEnumerable, поскольку основные данные (массив компонентов, список объектов на сцене) уже находятся в памяти игры.

// Типичный случай в Unity: использование IEnumerable
Component[] allComponents = gameObject.GetComponents<Component>();
IEnumerable<Renderer> renderers = allComponents.OfType<Renderer>();
// Запрос выполняется локально, перебирая массив 'allComponents'

IQueryable становится критически важным, когда Unity-приложение взаимодействует с внешней базой данных или сервером (например, для загрузки статистики игроков, предметов из магазина). В таких случаях вы используете IQueryable через ORM, как часть архитектуры данных.

// Пример с IQueryable в гибридном Unity-проекте с базой данных
// (используя, например, Entity Framework Core)
public async Task<List<InventoryItem>> LoadPlayerInventory(int playerId)
{
    // 'dbContext.Items' - это IQueryable
    IQueryable<InventoryItem> query = dbContext.Items
                                                .Where(item => item.PlayerId == playerId && item.IsEquipped)
                                                .OrderBy(item => item.Slot);
    // Запрос будет преобразован в эффективный SQL и выполнен на сервере БД.
    // В память игры передается только конечный список.
    return await query.ToListAsync();
}

Вывод

  • Используйте IEnumerable, когда работаете с коллекциями данных уже загруженных в память Unity-приложения (списки, массивы).
  • Используйте IQueryable, когда строите запросы к внешним источникам данных (базы данных, веб-сервисы), чтобы обеспечить максимальную производительность и минимизировать передачу данных. Это ключевой инструмент для разделения логики запроса и его фактического выполнения на удаленной системе.
В чём разница между IEnumerable и IQueryable? | PrepBro