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

Что такое коллекция?

1.6 Junior🔥 201 комментариев
#C# и ООП#Другое#Коллекции и структуры данных

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

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

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

Что такое коллекция в программировании?

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

Ключевые характеристики коллекций

  • Динамический размер: В отличие от массивов, многие коллекции (например, List<T>) могут автоматически увеличивать или уменьшать свою вместимость по мере добавления или удаления элементов.
  • Гетерогенность: Коллекции в .NET являются обобщенными (Generic), что позволяет хранить строго типизированные данные, повышая безопасность и производительность.
  • Разнообразие структур: Существуют разные типы коллекций, оптимизированные под конкретные сценарии использования: списки, словари, множества, очереди, стеки.
  • Стандартизированные интерфейсы: Большинство коллекций реализуют интерфейсы вроде IEnumerable<T>, ICollection<T>, IList<T>, что обеспечивает единообразные способы перебора и манипуляции данными.

Основные типы коллекций в C# (Unity)

1. List<T> (Список)

Наиболее часто используемая коллекция. Представляет упорядоченную коллекцию с доступом по индексу. Аналог динамического массива.

using System.Collections.Generic;

// Создание и работа со списком
List<GameObject> enemyList = new List<GameObject>();

// Добавление элементов (размер увеличивается автоматически)
enemyList.Add(enemy1);
enemyList.Add(enemy2);

// Доступ по индексу
GameObject firstEnemy = enemyList[0];

// Перебор
foreach (GameObject enemy in enemyList) {
    enemy.GetComponent<Enemy>().TakeDamage(10);
}

// Удаление
enemyList.Remove(enemy1);

2. Dictionary<TKey, TValue> (Словарь)

Коллекция пар "ключ-значение", обеспечивающая быстрый поиск значения по уникальному ключу. Оптимизирована под поиск (близок к O(1)).

Dictionary<string, int> playerScores = new Dictionary<string, int>();

// Добавление данных
playerScores.Add("Player1", 100);
playerScores["Player2"] = 150; // Альтернативный синтаксис

// Быстрый поиск по ключу
if (playerScores.TryGetValue("Player1", out int score)) {
    Debug.Log($"Score: {score}");
}

// Использование для кэширования компонентов (паттерн оптимизации)
private Dictionary<Type, Component> _componentCache = new Dictionary<Type, Component>();

public T GetCachedComponent<T>() where T : Component {
    Type type = typeof(T);
    if (!_componentCache.ContainsKey(type)) {
        _componentCache[type] = GetComponent<T>();
    }
    return (T)_componentCache[type];
}

3. HashSet<T> (Множество)

Коллекция, хранящая только уникальные элементы, без гарантии порядка. Обеспечивает очень высокую скорость операций проверки принадлежности (Contains).

HashSet<Vector3Int> visitedCells = new HashSet<Vector3Int>();

// Добавление (дубликаты игнорируются)
visitedCells.Add(new Vector3Int(1, 2, 0));
visitedCells.Add(new Vector3Int(1, 2, 0)); // Не добавится

// Быстрая проверка наличия
if (visitedCells.Contains(new Vector3Int(1, 2, 0))) {
    Debug.Log("Клетка уже посещена");
}

4. Queue<T> и Stack<T> (Очередь и Стек)

Специализированные коллекции для определенных алгоритмов:

  • Queue (FIFO - First In, First Out): Как очередь в магазине. Идеально для обработки команд по порядку.
  • Stack (LIFO - Last In, First Out): Как стопка тарелок. Используется для отмены действий (Undo), обхода деревьев.
// Очередь для сообщений
Queue<string> messageQueue = new Queue<string>();
messageQueue.Enqueue("Damage received");
messageQueue.Enqueue("Enemy spotted");

// Обработка в порядке поступления
while (messageQueue.Count > 0) {
    ProcessMessage(messageQueue.Dequeue());
}

// Стек для истории перемещений
Stack<Vector3> positionHistory = new Stack<Vector3>();
positionHistory.Push(transform.position);
transform.position = new Vector3(10, 0, 0);

// Отмена перемещения (возврат к предыдущей позиции)
if (positionHistory.Count > 0) {
    transform.position = positionHistory.Pop();
}

Почему коллекции важны в Unity-разработке?

  • Гибкость управления игровыми объектами: List<GameObject> для пула врагов, Dictionary<string, PowerUp> для системы улучшений.
  • Производительность: Правильный выбор коллекции (Dictionary вместо List для частых поисков) критически влияет на FPS.
  • Работа с данными конфигурации: Сериализация List<WaveConfig> для настроек волн врагов в инспекторе Unity.
  • Оптимизация памяти: Использование HashSet для отслеживания уникальных состояний вместо многократных проверок в списке.

Важное замечание для Unity: Для часто изменяющихся коллекций в циклах Update() рекомендуется использовать предварительное выделение емкости (Capacity) или специализированные решения вроде ArrayPool для минимизации аллокаций и сборок мусора, которые могут вызывать просадки производительности.

Выбор правильного типа коллекции — это компромисс между требованиями к скорости операций (вставка, удаление, поиск), потреблением памяти и необходимой семантикой доступа к данным.

Что такое коллекция? | PrepBro