Подтвердить что ты не робот

Почему исключение "Index out out range" для List <T>, но не для массивов?

Когда я инициализирую массив и элементы доступа с помощью индексатора, это работает отлично:

object[] temp = new object[5];
temp[0] = "bar";

Теперь я ожидал бы, что то же самое будет работать для List<T>, поскольку вы можете его инициализировать, передав способность конструктору:

List<object> temp = new List<object>(5);
temp[0] = "bar";

Эта последняя строка, однако, вызывает следующее исключение:

Индекс оказался вне допустимого диапазона. Должен быть неотрицательным и меньше размера коллекции

Почему это происходит для типа List<T>, но не для массива? Поскольку массивы представляют собой только абстракции нижнего уровня для коллекций для CLR, то почему это исключение происходит?


Оригинальный вопрос от Awais Mahmood.

4b9b3361

Ответ 1

Короткий ответ: Потому что 5 очень разные вещи.

Длинный ответ:

При инициализации массива вы устанавливаете его размер, и этот размер фиксируется. После этого массив не может расти или сокращаться. Следовательно,

object[] temp = new object[5];

означает, что вы создаете новый массив с 5 элементами. Следовательно, вы можете получить доступ к этим элементам сразу после создания массива.

Для списков размер является переменной. Экземпляры List<T> class внутренне используют массив для хранения своих элементов, а когда вы добавляете или удаляете элементы в списке, этот массив заменяется с большим или меньшим массивом. В каждом из этих случаев все элементы, которые остаются в списке, копируются из предыдущего массива в новый. Поскольку это довольно дорогостоящая операция, внутренний массив имеет некоторые накладные расходы на неиспользуемые элементы. Пока элементы добавляются в список и размер этого внутреннего массива не превышен, массив не нужно заменять.

5, которые вы передаете конструктору списка, это начальный размер этого внутреннего массива:

List<object> temp = new List<object>(5);

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