В чем отличие между массивом (T [ ]) и списком (List )?csharp-94

Основные различия

Характеристика Массив (T[]) Список (List<T>)
Размер Фиксированный Динамически изменяемый
Выделение памяти Один блок Внутренний массив + логика
Производительность Быстрее для чтения Быстрее для модификаций
Методы Базовые операции Богатый API
Инициализация Четкое указание размера Гибкое добавление элементов

1. Структура и память

Массив:

int[] array = new int[10]; // Фиксированный размер
  • Непрерывный блок памяти
  • Размер определяется при создании
  • Хранит элементы непосредственно в себе

Список:

List<int> list = new List<int>(); // Начальная емкость 0
  • Оборачивает внутренний массив (T[] _items)
  • Динамически увеличивает емкость (обычно в 2 раза)
  • При добавлении элементов может создавать новый массив

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

Доступ по индексу:

  • Массив: O(1) - прямой доступ
  • Список: O(1) - доступ к внутреннему массиву

Добавление элементов:

array[0] = 5; // Только если индекс в границах
list.Add(5);  // Автоматическое расширение
  • Массив: Невозможно без создания нового массива
  • Список: O(1) амортизированное время (при расширении O(n))

3. Функциональность

Массивы:

  • Базовые операции: Length, GetValue, SetValue
  • Многомерные и зубчатые массивы
  • Ковариантность (string[] → object[])

Списки:

list.AddRange(items);
list.RemoveAt(0);
list.IndexOf(42);
  • Богатый API: Add, Remove, Find, Sort и т.д.
  • Реализует IEnumerable, ICollection
  • Поддержка LINQ

4. Использование памяти

Массив:

  • Точное использование: sizeof(T) * length + overhead
  • Нет дополнительных накладных расходов

Список:

  • Обычно занимает больше памяти (запас capacity)
  • Дополнительные поля: _size, _version, _items

5. Особые случаи

stackalloc массивы:

unsafe {
    int* arr = stackalloc int[10]; // Только примитивы
}
  • Только для массивов
  • Размещение в стеке

ReadOnly коллекции:

List<int>.AsReadOnly();
IReadOnlyList<int> ro = array;
  • Массив можно использовать как IReadOnlyList
  • У List есть специальный метод

Когда что использовать?

Массив лучше когда:

  • Размер известен и не меняется
  • Критична производительность
  • Нужна работа с unsafe кодом
  • Требуется многомерная структура

Список лучше когда:

  • Размер динамически меняется
  • Нужны удобные методы работы
  • Частое добавление/удаление элементов
  • Работа с LINQ

Резюмируем:

хотя List использует массив внутри, это принципиально разные структуры данных. Массивы предлагают более низкоуровневый, но производительный интерфейс для работы с фиксированными наборами данных, тогда как List предоставляет удобный высокоуровневый API для динамических коллекций с автоматическим управлением памятью.