繁体   English   中英

为什么是列表的.Count <T> (Int32)初始大小为0?

[英]Why is the .Count of a List<T>(Int32) with initial size 0?

嗨,今天我偶然发现了List<T>(Int32) 我认为以下示例中的行为是相同的:

1。

var myList = new List<string>(5);
myList[1] = string.Empty;

2。

var myArray= new string[5];
myArray[1] = string.Empty;

第一个示例失败,我得到'System.ArgumentOutOfRangeException'。 第二个例子效果很好。

所以我在列表上尝试了.Count并且它表示它为0,当我把.Length放在数组时它说5。

在MSDN中它说:

初始化List类的新实例,该实例为空并具有指定的初始容量。

我认为这意味着列表具有我传入的初始大小。为什么不是这种情况?

提前致谢!

Count是列表中实际有多少元素, Capacity是内部数据结构的大小。 它旨在处理您已经知道大小的大型列表,因此在添加时不需要重复调​​整大小。

初始容量是指列表维护的内部阵列存储。

如果您希望保留100个项目并指定100作为初始容量,则可以避免内部调整数组大小的开销(实际上,列表可以避免创建新数组并复制前一个数组的值...)。

也许现在你已经意识到列表(以及许多其他集合类型)只是数组的抽象,以提供特定的语义:列表,集合,字典......

例如,具有100个初始容量项的列表集合可能会将项添加到已有100索引/槽的内部数组:

int[] array1 = new int[100];
array1[0] = 1;
// until...
array1[99] = 2;

...虽然没有提供良好的容量,但它可能需要在内部处理100个项目的插入:

int[] array2 = new int[3];
array2[0] = 1;
array2[1] = 2;
array2[2] = 3;

int[] array3 = new int[6];
array2.CopyTo(array3);
array3[3] = 4;
array3[4] = 5;
array3[5] = 6;

int[] array4 = new int[9];
array3.CopyTo(array4);
array4[6] = 7;
array4[7] = 8;
array4[8] = 9;
// and so on...

作为列表存储的整个内部数组已经进行了最小预留,但这只是一个实现细节。 如果您已经知道要添加到列表中的项目数量,那么提供初始容量会更好。

请注意,初始容量不会修复整个列表的最大容量。 这会损害列出的目的和语义:通过插入顺序 (FIFO, 先入先出 )下令对象的集合。 达到容量后,内部阵列将再次调整大小。

此外,由于较高级别的列表仅被描述为对象集合,因此您不能指望提供初始容量可以提供对内部存储索引的访问。 存在集合对象的内部数组的事实是一个实现细节,您需要依赖于高级细节:

// Above reason is why you CAN'T access myList[1]
var myList = new List<string>(5);
myList[1] = string.Empty;

更多详情

希望现在大多数.NET Framework源代码都可以在线获得。 您可以查看List<T>源代码,了解它在内部的工作原理:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM