修剪访问用于最小化集合的内存
例如
例如
List<string> myList = new List<string>();
如果我的包含2项后修剪访问容量列表将是2
同样,如果TrimExcess容量分别变为4或5或6,则list包含4或5或6
但如果列表包含3或7或15,为什么在TrimExcess之后容量分别变为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; } }
if语句仅在i = 3时才为真
任何人都可以让我知道原因
解决方法
这是List< T>的源代码:
public void TrimExcess() { int threshold = (int)(((double)_items.Length) * 0.9); if( _size < threshold ) { Capacity = _size; } }
其中_size是Count属性的后备字段,_items.Length是Capacity getter返回的内容.
所以基本上,如果没有使用超过10%的阵列插槽,TrimExcess只会将容量设置为Count.这就是为什么在你的一些测试中Count不等于容量.
评论中的另一个问题:
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
为什么第5行打印8?
空列表以0容量开始.
>插入第一个元素时,容量增加到4,即其默认容量.
>插入第五个元素时,容量增加到当前容量的两倍.因此,如果容量仍为4,则最多为8.
>插入第9个元素时,容量再次加倍,依此类推.
因此,当您插入第5个元素时,容量从4变为8.如果再插入两个元素,您将看到容量从8到16.
为什么7号线打印8?
我的回答的第一部分已经回答了这个问题.
现在我们知道为什么在调用TrimExcess之前容量是8.
由于阵列中未使用的空间*不到10%,TrimExcess什么都不做,而容量仍为8.
注意:实际上,有12.5%的未使用空间(阵列中有1个空闲插槽/ 8个可能的插槽).但是因为7 * 0.9被舍入为整数,所以阈值变为7.并且因为7 <0. 7返回false,没有任何反应.