C#中List.Add()内部如何向数组添加新元素?
.NET List.Add 底层工作原理与复刻实现
核心逻辑概述
List<T>内部依赖固定长度的私有数组存储元素,同时通过三个关键字段控制状态:
_items:实际存储元素的底层数组_size:当前已添加的元素总数(始终小于等于_capacity)_capacity:底层数组的总容量
当调用Add方法时,核心流程如下:
- 容量检查:判断当前
_size是否等于_capacity,如果相等说明数组已满,需要扩容 - 扩容操作:
- 初始状态下(
_capacity为0),第一次扩容会将容量设为4 - 后续扩容默认将容量翻倍(也可以通过
EnsureCapacity手动指定) - 创建一个新的、容量为目标值的数组,通过
Array.Copy高效复制旧数组的所有元素到新数组,替换_items引用
- 初始状态下(
- 添加元素:将新元素赋值到
_items[_size]的位置,然后_size自增1
复刻实现示例
下面是一个简化版的MyList<T>,核心逻辑和原生List<T>的Add方法对齐:
public class MyList<T> { private T[] _items; private int _size; private int _capacity; public MyList() { _capacity = 0; _items = Array.Empty<T>(); _size = 0; } public void Add(T item) { // 检查是否需要扩容 if (_size == _capacity) { EnsureCapacity(_capacity == 0 ? 4 : _capacity * 2); } // 添加元素并更新计数 _items[_size] = item; _size++; } private void EnsureCapacity(int newCapacity) { if (newCapacity <= _capacity) return; // 创建新数组并复制元素 T[] newItems = new T[newCapacity]; Array.Copy(_items, newItems, _size); _items = newItems; _capacity = newCapacity; } // 可选:实现获取元素的索引器 public T this[int index] { get { if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index)); return _items[index]; } } // 可选:返回当前元素数量 public int Count => _size; }
关键细节说明
- 原生
List<T>的扩容逻辑会做边界检查(比如最大容量限制),上面的简化版省略了这部分,但核心复制逻辑一致 Array.Copy是底层优化的方法,比手动循环复制效率高很多,这也是原生List高效的原因之一- 如果提前知道要添加的元素数量,可以调用
EnsureCapacity预先设置容量,避免多次扩容带来的性能开销
内容的提问来源于stack exchange,提问作者Yugraaj Sandhu
相关产品推荐
相关产品推荐

