Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
377 views
in Technique[技术] by (71.8m points)

c# - Does using the braced initializer on collection types set the initial capacity?

Does using the braced initializer on a collection type set it's capacity or do you still need to specify it?

That is, does:

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

result in the same as this:

var list = new List<string>(2){ "One", "Two" };
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Object initializer simply calls Add for each item.

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

As you can see, in this case parameterless constructor is called:

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 

So, you should set capacity manually:

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

Compiles into:

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

So, algorithm is pretty obvious - it calls constructor which you specified (parameterless by default) and then calls Add for each item.

NOTE: I know, that default capacity is 4 for List<T> and I verified what happens if we pass more than 4 items in initializer (e.g. maybe compiler determines which constructor to call depending on items count) but result is same - parameterless constructor is called by default.

I think purpose of collection initializers is creating small collections (1 - 8 items), thus there will be a little performance impact (only one resize if you will pass 8 items into initializer). Nobody expects you will use in-place initialization with 100 items. And if you are going to do that, you should use appropriate constructor of collection.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...