所在框架版本:.Net Framework 4.0.30319
1.部分变量
private const int _defaultCapacity = 4; //默认容量
private T[] _items; //元素数组
private int _size; //元素个数
private int _version; //版本号
[NonSerialized]
private object _syncRoot;
private static readonly T[] _emptyArray = new T[0]; //空的只读的数组
2.构造函数
public List() => this._items = List<T>._emptyArray; //如果没有传入初始容量,则给默认只读的空数组
public List(int capacity) //传入初始容量的情况
{
if (capacity < 0)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
if (capacity == 0) //如果传入的容量为0,依旧给默认只读的空数组
this._items = List<T>._emptyArray;
else //否则初始化元素数组
this._items = new T[capacity];
}
public List(IEnumerable<T> collection) //传入集合的情况
{
if (collection == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
if (collection is ICollection<T> objs) //如果传入的是个泛型集合
{
int count = objs.Count;
if (count == 0)
{
this._items = List<T>._emptyArray;
}
else
{
this._items = new T[count]; //初始化元素数组
objs.CopyTo(this._items, 0); //将集合的元素拷贝到数组中
this._size = count; //元素个数赋值
}
}
else //如果传入的是个非泛型集合
{
this._size = 0;
this._items = List<T>._emptyArray;
foreach (T obj in collection)
this.Add(obj); //将元素添加进数组
}
}
3.属性
public int Capacity //容量,可读可写
{
[__DynamicallyInvokable] get => this._items.Length;
[__DynamicallyInvokable] set
{
if (value < this._size)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_SmallCapacity);
if (value == this._items.Length) //如果传入的和元素数组长度相等,不做处理
return;
if (value > 0)
{
T[] objArray = new T[value]; //新建一个传入长度的数组
if (this._size > 0) //如果已有的元素个数大于0
Array.Copy((Array) this._items, 0, (Array) objArray, 0, this._size); //将原数组的元素拷贝到新的数组中
this._items = objArray; //重新赋值
}
else
this._items = List<T>._emptyArray; //重新给空数组
}
}
public int Count //列表长度,只读
{
[__DynamicallyInvokable] get => this._size; //返回元素个数
}
public T this[int index] //获取或设置指定索引处的元素
{
[__DynamicallyInvokable] get
{
if ((uint) index >= (uint) this._size) //如果索引大于当前元素个数,抛出异常
ThrowHelper.ThrowArgumentOutOfRangeException();
return this._items[index];
}
[__DynamicallyInvokable] set
{
if ((uint) index >= (uint) this._size)
ThrowHelper.ThrowArgumentOutOfRangeException();
this._items[index] = value; 设置对应元素
++this._version; //版本号更新
}
}
4.添加元素
public void Add(T item)
{
if (this._size == this._items.Length) //如果已满,则扩容
this.EnsureCapacity(this._size + 1);
this._items[this._size++] = item; //否则将元素添加到数组中
++this._version; //版本号更新
}
public void AddRange(IEnumerable<T> collection) => this.InsertRange(this._size, collection); //将指定集合的元素添加到末尾
public void InsertRange(int index, IEnumerable<T> collection)
{
if (collection == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
if ((uint) index > (uint) this._size)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index);
if (collection is ICollection<T> objs) //如果是个泛型集合
{
int count = objs.Count; //获得传入集合的元素个数
if (count > 0)
{
this.EnsureCapacity(this._size + count); //如果插入的元素个数大于0,则扩容
if (index < this._size) //插入位置小于当前元素数
Array.Copy((Array) this._items, index, (Array) this._items, index + count, this._size - index); //将插入位置后的所有元素移动到插入数量之后,空出一段位置
if (this == objs) //如果列表和参数集合是同一个
{
Array.Copy((Array) this._items, 0, (Array) this._items, index, index);
Array.Copy((Array) this._items, index + count, (Array) this._items, index * 2, this._size - index); //自己拼接自己就好
}
else //如果不同
{
T[] array = new T[count]; //新建一个长度为参数集合长度的数组
objs.CopyTo(array, 0); //将参数集合拷贝到数组中
array.CopyTo((Array) this._items, index); //再将数组拷贝到列表中
}
this._size += count; //元素个数更新
}
}
else //如果不是个泛型集合
{
foreach (T obj in collection)
this.Insert(index++, obj); //插入到列表中
}
++this._version; //版本号更新
}
5.扩容
private void EnsureCapacity(int min)
{
if (this._items.Length >= min) //如果列表的容量大于传入的参数,不做处理
return;
int num = this._items.Length == 0 ? 4 : this._items.Length * 2; //判断目前列表的容量是否为0,如果是,给最小的容量4,否则扩展到当前容量的两倍
if ((uint) num > 2146435071U) //限制,防止溢出
num = 2146435071;
if (num < min)
num = min;
this.Capacity = num; //给到容量
}
6.插入
public void Insert(int index, T item)
{
if ((uint) index > (uint) this._size) //如果索引大于当前元素个数,抛出异常
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_ListInsert);
if (this._size == this._items.Length) //如果满了,扩容
this.EnsureCapacity(this._size + 1);
if (index < this._size) //如果要插入的位置在列表中
Array.Copy((Array) this._items, index, (Array) this._items, index + 1, this._size - index); //插入之后的部分整体往后挪
this._items[index] = item; //对应元素插入
++this._size; //元素个数加一
++this._version; //版本号加一
}
7.查找
public bool Contains(T item)
{
if ((object) item == null) //如果要查找的为空
{
for (int index = 0; index < this._size; ++index) //遍历数组
{
if ((object) this._items[index] == null) //如果找到了空值
return true;
}
return false;
}
EqualityComparer<T> equalityComparer = EqualityComparer<T>.Default;
for (int index = 0; index < this._size; ++index)
{
if (equalityComparer.Equals(this._items[index], item)) //如果找到了
return true;
}
return false;
}
public bool Exists(Predicate<T> match) => this.FindIndex(match) != -1;
public int FindIndex(Predicate<T> match) => this.FindIndex(0, this._size, match);
public int FindIndex(int startIndex, Predicate<T> match) => this.FindIndex(startIndex, this._size - startIndex, match);
public int FindIndex(int startIndex, int count, Predicate<T> match)
{
if ((uint) startIndex > (uint) this._size)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
if (count < 0 || startIndex > this._size - count)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
if (match == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
int num = startIndex + count;
for (int index = startIndex; index < num; ++index) //遍历搜索范围
{
if (match(this._items[index])) //看是否有匹配条件的元素
return index; //返回下标
}
return -1; //没找到返回-1
}
public T FindLast(Predicate<T> match) //搜索与指定谓词所定义的条件相匹配的元素,并返回整个列表中的最后一个匹配元素
{
if (match == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
for (int index = this._size - 1; index >= 0; --index) //倒过来遍历
{
if (match(this._items[index]))
return this._items[index];
}
return default (T); //找不到返回默认值
}
public int FindLastIndex(Predicate<T> match) => this.FindLastIndex(this._size - 1, this._size, match);
public int FindLastIndex(int startIndex, Predicate<T> match) => this.FindLastIndex(startIndex, startIndex + 1, match);
public int FindLastIndex(int startIndex, int count, Predicate<T> match)
{
if (match == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
if (this._size == 0)
{
if (startIndex != -1)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
}
else if ((uint) startIndex >= (uint) this._size)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
if (count < 0 || startIndex - count + 1 < 0)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
int num = startIndex - count;
for (int index = startIndex; index > num; --index) //倒过来遍历
{
if (match(this._items[index]))
return index;
}
return -1; //找不到返回-1
}
8.清除
public bool Remove(T item)
{
int index = this.IndexOf(item); //查找匹配的第一个元素的索引
if (index < 0)
return false;
this.RemoveAt(index);
return true;
}
public void RemoveAt(int index)
{
if ((uint) index >= (uint) this._size)
ThrowHelper.ThrowArgumentOutOfRangeException();
--this._size; //元素个数减一
if (index < this._size)
Array.Copy((Array) this._items, index + 1, (Array) this._items, index, this._size - index); //要移除位置之后的元素全体往前提
this._items[this._size] = default (T); //最后一个元素给默认值
++this._version; //版本号加一
}
public int RemoveAll(Predicate<T> match) //移除与指定的谓词所定义的条件相匹配的所有元素
{
if (match == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
int index1 = 0; //不匹配索引
while (index1 < this._size && !match(this._items[index1]))
++index1;
if (index1 >= this._size)
return 0;
int index2 = index1 + 1; //匹配索引
while (index2 < this._size)
{
while (index2 < this._size && match(this._items[index2]))
++index2;
if (index2 < this._size)
this._items[index1++] = this._items[index2++]; //将不匹配元素放在一起
}
Array.Clear((Array) this._items, index1, this._size - index1); //清除所有匹配元素
int num = this._size - index1; //移除的元素个数
this._size = index1; //元素个数更新
++this._version; //版本号更新
return num;
}
public void RemoveRange(int index, int count) //移除一定范围的元素
{
if (index < 0)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
if (this._size - index < count)
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
if (count <= 0)
return;
int size = this._size;
this._size -= count; //移除后的元素个数
if (index < this._size)
Array.Copy((Array) this._items, index + count, (Array) this._items, index, this._size - index); //将不移除的元素前提
Array.Clear((Array) this._items, this._size, count); //剩余元素清除
++this._version; //版本号更新
}