在集合类型上使用支撑初始化程序是否设置了初始容量?

时间:2013-09-24 07:28:07

标签: c# collections

在集合类型上使用支撑初始化程序是否设置了它的容量,还是需要指定它?

那就是:

var list = new List<string>(){ "One", "Two" };

结果与此相同:

var list = new List<string>(2){ "One", "Two" };

4 个答案:

答案 0 :(得分:14)

对象初始化程序只需为每个项目调用Add

var list = new List<string>{ "One", "Two", "Three" };

如您所见,在这种情况下,无参数构造函数被称为:

L_0000: nop 
L_0001: newobj instance void [mscorlib]System.Collections.Generic.List`1<string>::.ctor()
L_0006: stloc.1 
L_0007: ldloc.1 
L_0008: ldstr "One"
L_000d: callvirt instance void [mscorlib]System.Collections.Generic.List`1<string>::Add(!0)
L_0012: nop 
L_0013: ldloc.1 
L_0014: ldstr "Two"
L_0019: callvirt instance void [mscorlib]System.Collections.Generic.List`1<string>::Add(!0)
L_001e: nop 
L_001f: ldloc.1 
L_0020: ldstr "Three"
L_0025: callvirt instance void [mscorlib]System.Collections.Generic.List`1<string>::Add(!0)
L_002a: nop 
L_002b: ldloc.1 

因此,您应手动设置容量:

var list = new List<string>(5){ "One", "Two", "Three" };

编译成:

L_0000: nop 
L_0001: ldc.i4.5 
L_0002: newobj instance void [mscorlib]System.Collections.Generic.List`1<string>::.ctor(int32)
// rest is same

因此,算法非常明显 - 它调用您指定的构造函数(默认情况下无参数),然后为每个项调用Add

注意:我知道,List<T>的默认容量是4,我验证了如果我们在初始化程序中传递了4个以上项目会发生什么(例如,编译器可能根据项目数确定要调用的构造函数),但结果是相同 - 默认情况下调用无参数构造函数。

我认为集合初始化程序的目的是创建小集合(1-8项),因此会产生一点性能影响(如果将8个项目传递给初始化程序,则只有一个调整大小)。没有人希望您将使用100个项目进行就地初始化。如果你打算这样做,你应该使用适当的收集构造函数。

答案 1 :(得分:3)

集合初始值设定项使用可用的Add方法将项​​目添加到集合中。因此,行为与使用空构造函数调用Add方法相同。

实际上,编译器会将对象初始化程序语法更改为对Add方法的调用。 因此,是否使用对象初始化程序是无关紧要的。重要的是你是否决定使用构造函数重载和实际添加的项目数量。

答案 2 :(得分:1)

使用无参数构造函数初始化List后,内部数组将设置为长度为0的数组。

当调用Add(),Insert()或InsertRange()时,将重新计算列表的容量:

  • 如果列表中没有其他元素,则容量设置为4 (默认容量)。
  • 如果有其他元素,则容量为 设置为元素数量的两倍。

如果指定容量,则会以该大小创建内部数组。

参考文献: DotNet来源:RefSrc \ Source.NET 4.5 \ 4.5.50709.0 \ net \ ndp \ clr \ src \ BCL \ System \ Collections \ Generic \ List.cs \ 597531 \ List.cs

答案 3 :(得分:0)

根据documentation并考虑到对象初始化器的计数为2,它最终也会设置容量。

  

容量始终大于或等于Count