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

Для чего используют List?

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

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

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

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

Для чего используют List в C# (Unity)?

В разработке игр на Unity с использованием C#, List<T> (список) является одной из самых часто используемых коллекций из пространства имён System.Collections.Generic. Его основное предназначение — динамическое хранение и управление упорядоченными наборами однотипных объектов, когда количество элементов заранее неизвестно или может меняться во время выполнения игры.

Ключевые преимущества и сценарии использования в Unity

  • Динамический размер (в отличие от массивов). Это критически важно в играх, где количество сущностей (врагов, пуль, предметов в инвентаре, точек пути) постоянно меняется.

    List<Enemy> activeEnemies = new List<Enemy>();
    // При появлении нового врага просто добавляем его
    activeEnemies.Add(new Enemy());
    // При смерти врага — удаляем
    activeEnemies.Remove(deadEnemy);
    
  • Удобные методы для манипуляции данными. List предоставляет богатый API для повседневных задач.

    *   `Add()`, `Remove()`, `Insert()` – добавление и удаление элементов.
    *   `Contains()`, `IndexOf()` – поиск элементов.
    *   `Sort()` – сортировка (например, врагов по расстоянию до игрока).
    *   `Find()`, `FindAll()` с предикатами – декларативный поиск по условию.
```csharp
// Найти ближайшего живого врага в радиусе
Enemy nearestEnemy = activeEnemies.Find(e => e.IsAlive && Vector3.Distance(player.position, e.position) < 10f);
// Получить список всех боссов
List<Enemy> bosses = activeEnemies.FindAll(e => e.IsBoss);
```
  • Совместимость с циклами и LINQ. List идеально работает с foreach и Language Integrated Query (LINQ), что делает код чище и выразительнее для операций фильтрации, проекции и агрегации данных.

    // Использование LINQ для сложных запросов
    using System.Linq;
    var sortedEnemies = activeEnemies.Where(e => e.IsVisible).OrderBy(e => e.Health).ToList();
    
  • Прямая работа с компонентами Unity. В Unity List<T> часто используется для хранения ссылок на компоненты или игровые объекты, полученные, например, через GetComponents() или заполненные через инспектор (с помощью атрибута [SerializeField]).

    [SerializeField] private List<Transform> _waypoints; // Заполняется в инспекторе
    private List<Rigidbody> _ragdollParts = new List<Rigidbody>();
    
    void Start() {
        GetComponentsInChildren(_ragdollParts); // Заполнение списка сразу
    }
    
  • Эффективность для итераций. Последовательное хранение данных в памяти обеспечивает высокую скорость перебора элементов в цикле, что является частой операцией в игровом цикле (например, Update() всех врагов).

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

  • Противопоставление массиву (T[]): Массив имеет фиксированную длину и используется, когда количество элементов точно известно и не изменится (например, сетка уровня, статический набор навыков). List — это обёртка над массивом, которая автоматически пересоздаёт его с большим размером при необходимости (с затратами на производительность, если это происходит часто).
  • Противопоставление LinkedList<T>: LinkedList эффективен для частых вставок/удалений в середине, но медленнее для произвольного доступа по индексу. В игровой логике доступ по индексу и итерации встречаются гораздо чаще.
  • Производительность: При работе с List важно:
    *   По возможности задавать **начальную ёмкость** (`capacity`) через конструктор, если предполагаемый размер известен, чтобы избежать множественных переаллокаций.
    *   Использовать `for` вместо `foreach` в **критичных по производительности участках кода** (например, в каждом кадре для тысяч объектов), чтобы избежать накладных расходов на создание энумератора.

Заключение

List<T> — это универсальный и гибкий инструмент для управления коллекциями данных в Unity. Он является «рабочей лошадкой» в типичных сценариях: пулы объектов, управление юнитами, инвентари, системы заданий, списки эффектов и многое другое. Понимание его сильных сторон (динамичность, удобный API) и ограничений (издержки на увеличение размера) позволяет применять его эффективно и осознанно, делая код чистым и производительным.