我已经了解了c#中的泛型和数组(我知道在c ++中使用指针的动态数组),我也知道数组是固定大小的,所以我们不能在初始化后改变它的大小,我们必须分配一个新的一个然后复制......
最近,我一直在使用ILspy来查看.net程序集的源代码,我发现List内部依赖于私有数组,但我无法弄清楚它是如何工作的,所以我想知道它在技术上是如何增长的或者在我编写它时在内存中重新调整大小?
答案 0 :(得分:22)
List<T>
分配一定大小的数组T[]
,并将其用作其项目的存储,直到数组填满为止。在发生这种情况后需要添加新项目时,列表会分配一个新的更大的数组,并将旧数组中的所有项目复制到新数组中。然后可以毫无问题地添加新项目。
由于此行为,将项目附加到List
被描述为amortized O(1)操作:由于后备阵列中有可用空间,因此大多数附加将花费一些时间,但某些追加将触发数组重新分配并花费更多时间。
从List
的公共界面也可以看出实现的方式:有一个Capacity
属性可以控制列表可以容纳多少项而无需调整大小,还有一个constructor允许你预先保留一些指定的容量(当你事先知道列表将至少达到一定的大小时,有助于避免不必要的调整大小操作。)