C#中ListT存放元素的工作机制

Celandine ·
更新时间:2024-11-01
· 1735 次阅读

List<T>是怎么存放元素?我们扒一段List<T>的一段源码来一窥究竟。

using System; using System.Diagnostic; using System.Collections.ObjectModel; using System.Security.Permissions; namespace System.Collections.Generic { ... [Serializable()] public class List<t> : IList<t>, System.Collections.IList { private const int _defaultCapacity = 4; private T[] _items; //List<T>内部是依靠数组_items存放数据的 private int _size; //数组的长度 private int _version; [NoSerialized] private Object _syncRoot; static T[] _emptyArray = new T[0]; //无参数构造函数 把_items设置成一个空的数组 public List() { _items = _emptyArray; } //此构造函数 给_items数组一个初始容量 public List(int capacity) { ... items = new T[capaicty]; } //此构造函数 把集合类型参数拷贝给_items数组 public List(IEnumerable<t> collection) { ... ICollection<t> c = collection as ICollection<t>; if(c != null) { int count = c.Count; //把构造函数集合类型参数的长度赋值给临时变量count _items = new T[count]; //List<T>内部维护的_items数组的长度和构造函数集合类型参数的长度一致 c.CopyTo(_items, 0); //把构造函数集合的所有元素拷贝到_items数组中去 _size = count; //_items数组的长度就是构造函数集合类型参数的长度 } else { _size = 0; _items = new T[_defaultCapacity]; ... } } //通过设置这个属性,改变List<t>内部维护的_items数组的长度 public int Capacity { get {return _items.Length; } set { if(value != _items.Length){ //如果当前赋值和List<t>维护的内部数组_items长度不一致 if(value < _size){ //TODO: 处理异常 } if(value > 0){ T[] newItems = new T[value]; //创建一个临时的、新的数组,长度为新的赋值 if(_size > 0){ //把临时的、新的数组拷贝给List<t>内部维护的数组_items,注意,这时_items的长度为新的赋值 Array.Copy(_items, 0, newItems, 0, _size); } } else { _items = _emptyArray; } } } } public void Add(T item) { if(_size == _items.Length) EnsureCapacity(_size + 1); _items[_size++] = item; ... } //确保List<t>内部维护的_items数组的长度至少是给定的值 //如果_items数组原先的长度比给定的值小,就让_items数组的长度设置为原先的长度的2倍 privat void EnsureCapacity(int min) { if(_items.Length < min){ int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Legnth * 2; if(newCapacity < min) newCapacity = min; Capacity = newCapacity; } } } }

由此可见,向List<T>中存放元素的大致过程是这样的:

List<T>内部维护着一个数组_items,用来存放T类型的元素。

当有新的T类型元素存放进来,即调用Add(T item)方法。

Add(T item)方法内部调用EnsureCapacity(int min)方法确保List<T>的Capaicty属性值至少在原先长度上加1,最多是原先长度的2倍。

在给Capacity赋值的过程中,对_items的长度进行了扩容。

扩容后,再把新的T类型元素存放进来。

简单地说:

当有新的元素存放到List<T>中时,List<T>先对其维护的内部数组进行扩容,然后再把新元素放进来。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对软件开发网的支持。如果你想了解更多相关内容请查看下面相关链接



C#

需要 登录 后方可回复, 如果你还没有账号请 注册新账号