为什么 List但数组不是

本文关键字:异常 数组 范围 List 索引 为什么 | 更新日期: 2023-09-27 18:32:20

当我初始化数组并使用索引器访问元素时,工作正常:

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的原始问题。

为什么 List<T 的“索引超出范围”异常>但数组不是

简短的回答:因为 5 做了非常不同的事情。

长答案:

初始化数组时,您可以设置其大小,并且该大小是固定的。阵列以后无法增长或收缩。因此

object[] temp = new object[5];

意味着您创建一个包含 5 个元素的新数组。因此,您可以在创建数组后立即访问这些元素。

对于列表,大小是可变的。List<T>类的实例在内部使用数组来存储其项,当您在列表中添加或删除项时,该数组将替换为更大或更小的数组。在上述每种情况下,列表中保留的所有项都会从上一个数组复制到新数组。由于这是一项相当昂贵的操作,因此内部阵列有一些未使用项目的开销。只要将项添加到列表中并且不超过该内部数组的大小,就不需要替换该数组。

传递给列表构造函数的 5 是该内部数组的初始大小:

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

这意味着,您创建的列表具有零个元素(因此例外),但内部数组初始化为 5 大小,因此您可以添加 5 个元素而无需替换内部数组。