簡體   English   中英

調整List的容量<T>

[英]Resize capacity of List<T>

我用Reflector閱讀了.NET4.0類System.Collections.Generic.List<T>的源代碼,我有一些問題。 這是代碼:

    [__DynamicallyInvokable]
    public void Add(T item)
    {
        if (this._size == this._items.Length)
        {
            this.EnsureCapacity(this._size + 1);
        }
        this._items[this._size++] = item;
        this._version++;
    }
    private void EnsureCapacity(int min)
    {
        if (this._items.Length < min)
        {
            int num = (this._items.Length == 0) ? 4 : (this._items.Length * 2);
            if (num > 0x7fefffff)
            {
                num = 0x7fefffff;
            }
            if (num < min)
            {
                num = min;
            }
            this.Capacity = num;
        }
    }
    [__DynamicallyInvokable]
    public int Capacity
    {
        // omitted code

        set
        {
            if (value < this._size)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_SmallCapacity);
            }
            if (value != this._items.Length)
            {
                if (value > 0)
                {
                    T[] destinationArray = new T[value];
                    if (this._size > 0)
                    {
                        Array.Copy(this._items, 0, destinationArray, 0, this._size);
                    }
                    this._items = destinationArray;
                }
                else
                {
                    this._items = List<T>._emptyArray;
                }
            }
        }
    }
  • 它是通過將所有元素復制到新數組來調整數組大小的最佳方式還是唯一方法?
  • 為什么用“0x7fefffff”檢查“num”? 為什么“0x7fefffff”特別?
  • 為什么他們可以直接使用“4”和“0x7fefffff”? 他們不是神奇的數字嗎?

    謝謝。

這是原始源代碼(對於.NET 4.0,我相信):

    // 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) { 
            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; 
        } 
    }

至於你的問題:

  • 是的,您無法調整現有陣列的大小。 但是, Array.Resize允許您執行List.Capacity所做的事情,但代碼較少。 它創建新數組,復制元素,並為您分配新數組。
  • 如果查看原始代碼,很明顯限制是CLR中數組的大小。 看起來數組可以達到int.MaxValue元素長,減去0x100000個插槽,可能是陣列開銷。 我真的不能說具體的那些插槽是什么。
  • 在原始代碼中,它們是常量。 C#編譯器不編譯對常量的引用。 它只存儲值。 這就是常量在反編譯代碼中成為幻數的原因。

它是通過將所有元素復制到新數組來調整數組大小的最佳方式還是唯一方法?

是的,這是調整陣列大小的唯一方法。

對於給定大小的數組,只為該數組分配了該部分內存,周圍的內存可以分配給其他內容,因此您不能簡單地擴展內存,需要更大的插槽。

為什么用“0x7fefffff”檢查“num”? 為什么“0x7fefffff”特別?

請參閱MSDN

但是,該陣列仍將限制為總共40億個元素,並且在任何給定維度中最大索引為0X7FEFFFFF (對於字節數組和單字節結構數組,為0X7FFFFFC7)。

我找不到任何文件來說明為什么 0X7FEFFFFF是最大允許的大小(他們可能有一些不錯的理由來達到這樣的限制)。

為什么他們可以直接使用“4”和“0x7fefffff”? 他們不是神奇的數字嗎?

const可能在這里有意義。

這可能不是原來的代碼看起來完全像什么(如USR提到,它可能已經被反編譯),因此確實可以一直const的使用。

如果它恰好是原始代碼的樣子,我確信只有開發人員可以告訴你為什么他們做了他們所做的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM