internal T[] _items; // Do not rename (binary serialization) internalint _size; // Do not rename (binary serialization) privateint _version; // Do not rename (binary serialization) privatestaticreadonly T[] s_emptyArray = new T[0]; publicList() { _items = s_emptyArray; }
// Constructs a List with a given initial capacity. The list is // initially empty, but will have room for the given number of elements // before any reallocations are required. // publicList(int capacity) { if (capacity < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
if (capacity == 0) _items = s_emptyArray; else _items = new T[capacity]; } }
// Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow. // Note that this check works even when _items.Length overflowed thanks to the (uint) cast if ((uint)newcapacity > Array.MaxLength) newcapacity = Array.MaxLength;
// If the computed capacity is still less than specified, set to the original argument. // Capacities exceeding Array.MaxLength will be surfaced as OutOfMemoryException by Array.Resize. if (newcapacity < capacity) newcapacity = capacity;
Capacity = newcapacity; }
publicint Capacity { get => _items.Length; set { if (value < _size) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_SmallCapacity); }
if (value != _items.Length) { if (value > 0) { T[] newItems = new T[value]; if (_size > 0) { Array.Copy(_items, newItems, _size); } _items = newItems; } else { _items = s_emptyArray; } } } }
publicvoidInsert(int index, T item) { // Note that insertions at the end are legal. if ((uint)index > (uint)_size) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_ListInsert); } if (_size == _items.Length) Grow(_size + 1); if (index < _size) { Array.Copy(_items, index, _items, index + 1, _size - index); } _items[index] = item; _size++; _version++; }
同样,先检查容量是否足够,之后向后覆盖,接下来将元素放入即可。
Clear
publicvoidClear() { _version++; if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) { int size = _size; _size = 0; if (size > 0) { Array.Clear(_items, 0, size); // Clear the elements so that the gc can reclaim the references. } } else { _size = 0; } }
publicboolContains(T item) { // PERF: IndexOf calls Array.IndexOf, which internally // calls EqualityComparer<T>.Default.IndexOf, which // is specialized for different types. This // boosts performance since instead of making a // virtual method call each iteration of the loop, // via EqualityComparer<T>.Default.Equals, we // only make one virtual call to EqualityComparer.IndexOf.
return _size != 0 && IndexOf(item) != -1; }
同样这里是通过IndexOf来寻找元素
ToArray
public T[] ToArray() { if (_size == 0) { return s_emptyArray; }
public T this[int index] { get { // Following trick can reduce the range check by one if ((uint)index >= (uint)_size) { ThrowHelper.ThrowArgumentOutOfRange_IndexException(); } return _items[index]; }
set { if ((uint)index >= (uint)_size) { ThrowHelper.ThrowArgumentOutOfRange_IndexException(); } _items[index] = value; _version++; } }