C# 修剪后的容量超过列表中的容量<;T>;

C# 修剪后的容量超过列表中的容量<;T>;,c#,C#,修剪访问用于最小化集合的内存 比如说 List<string> myList = new List<string>(); List myList=new List(); 如果我的列表在修剪后包含2项,则列表的访问容量将为2 如果列表中包含4或5或6,则剩余容量将分别变为4或5或6 但若列表包含3、7或15,为什么容量在超出后分别变为4、8或16 即使在这之后,我发现了另一个奇怪的行为 如果我运行以下代码 List<int> myList = new L

修剪访问用于最小化集合的内存 比如说

 List<string> myList = new List<string>();
List myList=new List();
如果我的列表在修剪后包含2项,则列表的访问容量将为2

如果列表中包含4或5或6,则剩余容量将分别变为4或5或6

但若列表包含3、7或15,为什么容量在超出后分别变为4、8或16

即使在这之后,我发现了另一个奇怪的行为 如果我运行以下代码

 List<int> myList = new List<int>();
            for (int i = 1; i <= 100; i++)
            {
                myList.Add(1);
                myList.TrimExcess();
                if (myList.Capacity != myList.Count())
                {
                    var different = myList.Capacity;
                }
            }
List myList=new List();
对于(int i=1;i取自

然而,重新分配和复制大型列表的成本可能相当大,因此,如果列表的容量超过容量的90%,TrimOverse方法将不起任何作用。这避免了为相对较小的收益而产生巨大的重新分配成本


这意味着,在大多数情况下,List.trimOverse()调用不起任何作用,因此List.Count和List.Capacity之间存在差异

我不知道原因,但我决定找出原因:

public void TrimExcess()
{
    int num = (int) (this._items.Length * 0.9);
    if (this._size < num)
    {
        this.Capacity = this._size;
    }
}

以下是
列表的源代码:

为什么第5行打印8? 空列表以0容量开始

  • 插入第一个元素时,容量将增加到默认容量4
  • 当插入第五个元素时,容量将增加到当前容量的两倍。因此,如果容量仍然为4,则将增加到8
  • 插入第9个元素时,容量将再次加倍,依此类推
因此,当您插入第5个元素时,容量从4变为8。如果您再插入两个元素,您将看到容量从8变为16

为什么第7行打印8?

我在回答的第一部分已经回答了这个问题

现在我们知道了为什么在调用
TrimOverse
之前容量是8。 由于阵列中的未使用空间*不到10%,因此,
trimposure
什么也不做,容量保持在8

注意:实际上,有12.5%的未使用空间(阵列中1个空闲插槽/8个可能的插槽)。
但是因为7*0.9被四舍五入为整数,所以
阈值变为7。而且因为
7<7
返回false,所以什么也不会发生。

列表容量c总是在c中∈ {2^x}|x∈ 如果是这样,那么为什么循环中如果计数为7,则容量在修剪后为7?如果计数为7,则容量在修剪后为8?如果是这样,那么为什么循环中如果计数为7,则容量在修剪后为7?如果计数为7,则容量在修剪后为78@slashshogdhe我不确定我是否理解了你的问题。你能重新表述一下吗?我添加了一个示例,展示了两个用例,其中(Count=7和Capacity=7)和(Count=7和Capacity=8)。当I=7List myList=new List()时,请运行我的代码并检查容量;对于(int I=1;I当
I
为7时,计数和容量也为7。有什么奇怪的?
list.Capacity = list.Size;
  public void TrimExcess() {
        int threshold = (int)(((double)_items.Length) * 0.9);
        if( _size < threshold ) {
            Capacity = _size;
        }
    }
   1     List<int> myList = new List<int>
   2         {
   3             1,2,3,4,5,6,7 // equivalent to calling `Add` 7 times
   4         };
   5     Console.WriteLine(myList.Capacity); // prints 8 
   6     myList.TrimExcess();
   7     Console.WriteLine(myList.Capacity); // prints 8