linq-ToList


public class MyList 
    {
        private int _size;
        internal T[] _items; // Do not rename (binary serialization)
        private static readonly T[] s_emptyArray = new T[0];
        private int _version; // Do not rename (binary serialization)
        private const int DefaultCapacity = 4;

        public MyList(IEnumerable collection)
        {
            if (collection == null)
                //ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);

                if (collection is ICollection c)
                {
                    int count = c.Count;
                    if (count == 0)
                    {
                        _items = s_emptyArray;
                    }
                    else
                    {
                        _items = new T[count];
                        c.CopyTo(_items, 0);
                        _size = count;
                    }
                }
                else
                {
                    _items = s_emptyArray;
                    using (IEnumerator en = collection?.GetEnumerator())
                    {
                        while (en.MoveNext())
                        {
                            Add(en.Current);
                        }
                    }
                }
        }

        // Adds the given object to the end of this list. The size of the list is
        // increased by one. If required, the capacity of the list is doubled
        // before adding the new element.
        // 如果需要,列表的容量将增加一倍
        // 在添加新元素之前。
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Add(T item)
        {
            _version++;
            T[] array = _items;
            int size = _size;
            if ((uint)size < (uint)array.Length)
            {
                _size = size + 1;
                array[size] = item;
            }
            else
            {
                AddWithResize(item);
            }
        }

        // Non-inline from List.Add to improve its code quality as uncommon path
        // 列表中的非内联。添加以提高其代码质量
        [MethodImpl(MethodImplOptions.NoInlining)]
        private void AddWithResize(T item)
        {
            Debug.Assert(_size == _items.Length);
            int size = _size;
            Grow(size + 1);
            _size = size + 1;
            _items[size] = item;
        }
        /// 
        /// Increase the capacity of this list to at least the specified .
        /// 将此列表的容量至少增加到指定的/// 
        /// The minimum capacity to ensure.
        private void Grow(int capacity)
        {
            Debug.Assert(_items.Length < capacity);

            int newcapacity = _items.Length == 0 ? DefaultCapacity : 2 * _items.Length;

            // 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
            // 在遇到溢出之前,允许列表增长到最大可能容量(~2G个元素)。
            // 请注意,即使由于(uint)强制转换而导致_items.Length溢出,此检查仍有效
            // Array.MaxLength
            if ((uint)newcapacity > 0X7FFFFFC7) newcapacity = 0X7FFFFFC7;

            // 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.
            //如果计算的容量仍然小于指定的容量,请设置为原始参数。
            //超过Array.MaxLength的容量将由Array.Resize显示为OutOfMemoryException。
            if (newcapacity < capacity) newcapacity = capacity;

            Capacity = newcapacity;
        }


        // Gets and sets the capacity of this list.  The capacity is the size of
        // the internal array used to hold items.  When set, the internal
        // array of the list is reallocated to the given capacity.
        // 获取并设置此列表的容量。容量是指容量的大小
        // 用于保存项目的内部数组。设置后,内部
        // 列表的数组被重新分配到给定的容量。
        public int 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;
                    }
                }
            }
        }

    }

具体实现:

String[] languages = { "c++", "Java", "C#", "VB.net", "VC.net", "PHP", "Python", "GO" };
            //var query = from item in languages
            //            group item by item.Length into lengthGroups
            //            orderby lengthGroups.Key
            //            select lengthGroups;
            //var query2 = languages.ToLookup(x => x.Length);
            //foreach (var item in query2)
            //{
            //    Console.WriteLine(item.Key);
            //    foreach (var lengthGroupItem in item)
            //    {
            //        Console.WriteLine(lengthGroupItem);
            //    }
            //}

            MyList myList = new MyList<string>(languages);

源码中主要内存分配的优化,add的实现是array[index] = value;