我可以初始化List<int> like new List<int>{1,2,3,4,5};
但是List<T>
没有接受单个参数的构造函数。
所以我试图通过调试器运行它,它似乎是调用Add方法。
那么编译器如何知道调用哪个方法来添加每个元素。
这可能是一个愚蠢的问题,但我有点困惑。
由于
答案 0 :(得分:9)
每个具有Add和implements IEnumerable方法的类型都可以通过这种方式初始化。 编译器只是编译代码,就像使用了这个Add方法一样。
看看here
答案 1 :(得分:8)
这是一个集合初始值设定项,C# 3.0 language feature。它要求:
IEnumerable
(虽然这从未用于初始化)Add
方法它只是为每个术语调用Add
方法。
如果Add
接受多个值,您也可以使用元组,例如字典。然后每个术语都是{key,value}
:
new Dictionary<int,string> {{1,"abc"},{2,"def"}};
有关将其用于定制类型的示例:
class Program
{
static void Main()
{
new Foo { 1, "abc", { 2, "def" } };
}
}
class Foo : IEnumerable
{
public void Add(int a) { }
public void Add(string b) { }
public void Add(int a, string b) { }
// must implement this!! (but never called)
IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
}
答案 2 :(得分:6)
看看这个方法。
public void CreateList()
{
List<int> list = new List<int> { 1, 2, 3, 4, 5 };
}
编译完成后,MSIL看起来像这样..
.method public hidebysig instance void CreateList() cil managed
{
// Code size 50 (0x32)
.maxstack 2
.locals init ([0] class [mscorlib]System.Collections.Generic.List`1<int32> list,
[1] class [mscorlib]System.Collections.Generic.List`1<int32> '<>g__initLocal0')
IL_0000: nop
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
IL_0006: stloc.1
IL_0007: ldloc.1
IL_0008: ldc.i4.1
IL_0009: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_000e: nop
IL_000f: ldloc.1
IL_0010: ldc.i4.2
IL_0011: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_0016: nop
IL_0017: ldloc.1
IL_0018: ldc.i4.3
IL_0019: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_001e: nop
IL_001f: ldloc.1
IL_0020: ldc.i4.4
IL_0021: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_0026: nop
IL_0027: ldloc.1
IL_0028: ldc.i4.5
IL_0029: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_002e: nop
IL_002f: ldloc.1
IL_0030: stloc.0
IL_0031: ret
} // end of method Program::CreateList
正如您所看到的,它只是一个语法糖,编译器通过连续调用Add()来取代初始化。
答案 3 :(得分:3)
new List{ 1, 2, 3, 4, 5 }
只是句法'糖'。在封面下,它只会为每个项目调用Add
方法。
答案 4 :(得分:0)
由于new List<int>{1,2,3,4,5}
是数组初始化,我更倾向于认为它在魔法内部工作,因为我不能影响它发生的方式。考虑到它,它可能定义了在元数据中向元素添加元素的默认方法,其中[]
由索引完成,而实现IList
的元素由Add
方法完成。