Основные различия
Характеристика | Массив (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 для динамических коллекций с автоматическим управлением памятью.