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

Tim*_*Tim 16 c# collections

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

那就是:

var list = new List<string>(){ "One", "Two" };
Run Code Online (Sandbox Code Playgroud)

结果与此相同:

var list = new List<string>(2){ "One", "Two" };
Run Code Online (Sandbox Code Playgroud)

Ser*_*kiy 14

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

var list = new List<string>{ "One", "Two", "Three" };
Run Code Online (Sandbox Code Playgroud)

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

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 
Run Code Online (Sandbox Code Playgroud)

所以,你应该手动设置容量:

var list = new List<string>(5){ "One", "Two", "Three" };
Run Code Online (Sandbox Code Playgroud)

编译成:

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
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 调用无参数构造函数时,将内部数组设置为0,然后添加行并将容量重置为前一个元素计数的4或2倍,后者的值更高. (4认同)