Source code parsing comments for C# List

List variable-length generic list

Source address: Reference Source https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs

Field (intercept part):


private T[] _items;//核心是一个数组
private int _size;//数组长度(有效数据长度)
private int _version;
private const int _defaultCapacity = 4;//默认容量

Function (addition, deletion, modification and query):

Increase: Add

        // before adding the new element.
        public void Add(T item) {
            if (_size == _items.Length) EnsureCapacity(_size + 1);//检查是否要扩容
            _items[_size++] = item;//直接添加在末尾,并且长度加一
            _version++;
        }
        
        // Ensures that the capacity of this list is at least the given minimum
        // value. If the currect capacity of the list is less than min, the
        // capacity is increased to twice the current capacity or to min,
        // whichever is larger.
        private void EnsureCapacity(int min) {
            if (_items.Length < min) {
            //计算新容量,如果当前容量为0使用默认容量(4):否则使用当前容量的两倍
            //如果新容量大于Array的限定最大长度,新容量应当为Array的限定长度;
            //如果新容量小于传入的最小支持长度,新容量应当为输入的指定长度;
                int newCapacity = _items.Length == 0? _defaultCapacity : _items.Length * 2;
                // 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.MaxArrayLength) newCapacity = Array.MaxArrayLength;
                if (newCapacity < min) newCapacity = min;
                Capacity = newCapacity;
            }
        }  

Insert: Insert

Core code: Array.Copy(_items, index, _items, index + 1, _size - index); uses Array's Copy to directly copy a whole section of memory;

// Inserts an element into this list at a given index. The size of the list
// is increased by one. If required, the capacity of the list is doubled
// before inserting the new element.
// 
public void Insert(int index, T item) {
    // Note that insertions at the end are legal.
    if ((uint) index > (uint)_size) {
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_ListInsert);
    }
    Contract.EndContractBlock();
    if (_size == _items.Length) EnsureCapacity(_size + 1);
    if (index < _size) {
        Array.Copy(_items, index, _items, index + 1, _size - index);
    }
    _items[index] = item;
    _size++;            
    _version++;
}

删:Remove,RemoveAt,RemoveRange

Core code: Array.Copy(_items, index + 1, _items, index, _size - index); Use Array's Copy to directly copy a whole section of memory;


// Removes the element at the given index. The size of the list is
// decreased by one.
// 
public bool Remove(T item) {
    int index = IndexOf(item);
    if (index >= 0) {
        RemoveAt(index);
        return true;
    }

    return false;
}

// Removes the element at the given index. The size of the list is
// decreased by one.
// 
public void RemoveAt(int index) {
    if ((uint)index >= (uint)_size) {
        ThrowHelper.ThrowArgumentOutOfRangeException();
    }
    Contract.EndContractBlock();
    _size--;
    if (index < _size) {
        Array.Copy(_items, index + 1, _items, index, _size - index);
    }
    _items[_size] = default(T);
    _version++;
}

// Removes a range of elements from this list.
// 
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 (_size - index < count)
        ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
    Contract.EndContractBlock();

    if (count > 0) {
        int i = _size;
        _size -= count;
        if (index < _size) {
            Array.Copy(_items, index + count, _items, index, _size - index);
        }
        Array.Clear(_items, _size, count);
        _version++;
    }
}

Change: List [ index ]

public T this[int index] {
    get {
        // Following trick can reduce the range check by one
        if ((uint) index >= (uint)_size) {
            ThrowHelper.ThrowArgumentOutOfRangeException();
        }
        Contract.EndContractBlock();
        return _items[index]; 
    }

    set {
        if ((uint) index >= (uint)_size) {
            ThrowHelper.ThrowArgumentOutOfRangeException();
        }
        Contract.EndContractBlock();
        _items[index] = value;
        _version++;
    }
}

check:

Contians()


// Contains returns true if the specified element is in the List.
// It does a linear, O(n) search.  Equality is determined by calling
// item.Equals().
//
public bool Contains(T item) {
    if ((Object) item == null) {
        for(int i=0; i<_size; i++)
            if ((Object) _items[i] == null)
                return true;
        return false;
    }
    else {
        EqualityComparer<T> c = EqualityComparer<T>.Default;
        for(int i=0; i<_size; i++) {
            if (c.Equals(_items[i], item)) return true;
        }
        return false;
    }
}

Clear: Clear

// Clears the contents of List.
public void Clear() {
    if (_size > 0)
    {
        Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
        _size = 0;
    }
    _version++;
}

Copy: CopyTo

// Copies a section of this list to the given array at the given index.
// 
// The method uses the Array.Copy method to copy the elements.
// 
public void CopyTo(int index, T[] array, int arrayIndex, int count) {
    if (_size - index < count) {
        ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
    }
    Contract.EndContractBlock();
    
    // Delegate rest of error checking to Array.Copy.
    Array.Copy(_items, index, array, arrayIndex, count);
}

public void CopyTo(T[] array, int arrayIndex) {
    // Delegate rest of error checking to Array.Copy.
    Array.Copy(_items, 0, array, arrayIndex, _size);
}

other:

The basic interface flow of List:

//List<T> 类
public class List<T> : IList<T>, System.Collections.IList, IReadOnlyList<T>
{
        //这里要实现下列的所有接口
}

//IList<T> 接口
public interface IList<T> : ICollection<T>
{
        T this[int index] { 
            get;
            set;
        }
    
        int IndexOf(T item);
    
        void Insert(int index, T item);

        void RemoveAt(int index);
}

//ICollection<T> 接口 C#集合类的接口
public interface ICollection<T> : IEnumerable<T>
{       
        int Count { get; }
 
        bool IsReadOnly { get; }
 
        void Add(T item);
 
        void Clear();
 
        bool Contains(T item); 
                
        void CopyTo(T[] array, int arrayIndex);

        bool Remove(T item);

}

//IEnumerable<out T> 接口
public interface IEnumerable<out T> : IEnumerable
{
        new IEnumerator<T> GetEnumerator();
}

//IEnumerable 接口
public interface IEnumerable
{
        IEnumerator GetEnumerator();
}

Guess you like

Origin blog.csdn.net/weixin_40695640/article/details/130293849