为啥 List<T> 的“索引超出范围”异常,但数组却没有?
Posted
技术标签:
【中文标题】为啥 List<T> 的“索引超出范围”异常,但数组却没有?【英文标题】:Why "Index was out of range" exception for List<T> but not for arrays?为什么 List<T> 的“索引超出范围”异常,但数组却没有? 【发布时间】:2016-05-05 20:09:31 【问题描述】:当我使用索引器初始化数组并访问元素时,效果很好:
object[] temp = new object[5];
temp[0] = "bar";
现在我希望 List<T>
也可以使用同样的方法,因为您可以通过将容量传递给构造函数来对其进行初始化:
List<object> temp = new List<object>(5);
temp[0] = "bar";
然而,最后一行会引发以下异常:
索引超出范围。必须是非负数且小于集合的大小
为什么List<T>
类型会发生这种情况,而不是数组?既然数组只是 CLR 集合的低级抽象,那么为什么会出现这个异常呢?
question原创Awais Mahmood。
【问题讨论】:
你可以找到关于这个问题的所有元讨论over here。 @RobertHarvey:谢谢——尽管如此,我还是重新添加了关于原作者的简短评论,因为我不想看起来像一个抄袭者,在不给予信任的情况下复制别人的问题。跨度> 【参考方案1】:简答:因为 5 做了非常不同的事情。
长答案:
当初始化一个数组时,你设置它的大小,这个大小是固定的。阵列以后不能增长或缩小。因此,
object[] temp = new object[5];
表示您创建一个包含 5 个元素的新数组。因此,您可以在创建数组后立即访问这些元素。
对于列表,大小是可变的。 List<T>
class 的实例在内部使用一个数组来存储它们的项目,当您在列表中添加或删除项目时,该数组将被更大或更小的数组替换。在每种情况下,列表中保留的所有项目都会从前一个数组复制到新数组。由于这是一项相当昂贵的操作,内部数组有一些未使用项的开销。只要将项目添加到列表中并且不超过该内部数组的大小,就不需要替换该数组。
您传递给列表构造函数的 5 是该内部数组的初始大小:
List<object> temp = new List<object>(5);
这意味着,您创建的列表有 零个元素(因此例外),但内部数组初始化为 5 的大小,因此您可以添加 5 个元素而不需要内部数组被替换。
【讨论】:
@SririamSakthivel:感谢您的编辑。然而,我真的认为replaced 比resized 更有意义。答案的重点是数组不会得到resized,但列表中有一个内部数组替换为新的、更大或更小的数组实例。 也许你应该提到要修复他的列表代码,他应该将行从temp[i] = criteria[i + 1].ToString();
更改为temp.Add(criteria[i + 1].ToString());
以上是关于为啥 List<T> 的“索引超出范围”异常,但数组却没有?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在使用 readlines() 读取文件时出现列表索引超出范围错误?