01—问题缘起
严格来说应该是List<T>,因为.NET的核心基础类库中,并没有List,作为泛型类型的List<T>,对应的非泛型类型是ArrayList。
List被称作“列表”,相信大家对于"队列"和"链表"都很熟悉,但是"列表"似乎有些陌生,课本教材中将广义表称为列表,这个广义表的定义是:一个多层次的数据结构。直白的说就是表中的元素类型可以不同,这显然不是.NET中List<T>。
这显然也没有解答我们问题。
02—初识List
从源码及注释中可知:List<T>是基于数组实现的可扩容的列表。
看一下这几个私有变量:
T[] _items:是实际的存储类型,默认构造函数,将_items赋值为一个空数组。
int _size:记录当前列表中的元素数量。
03—List如何扩容
那列表是如何实现数组长度变化的呢?下面3个方法给了我们答案。
从源码可知,私有变量_size记录了列表中实际的元素数量,当调用Add(T item)添加元素时,会将_size与_item.Length进行对比,判断当前数组是否已满,首次添加元素时,分配的数组默认长度为4,否则重新分配一个2倍长度的数组,然后将原先的元素拷贝到新数组中,实现数组的自动扩容。
04—List使用小技巧
1.在已知数据长度的情况下,初始化时,应指定初始长度。
3.在.NET 6中,新增了一个方法public int EnsureCapacity(int capacity),推荐调用这个方法进行列表扩容,只要参数capacity不小于0,方法就不会报错。
05—总结
说明:文中源码基于.NET 6.0版本,在整理文章内容的过程中,还参考对比了.NET Framework 4.8 、.NET 5.0 几个不同版本的代码,不同版本间略有异。