在C#3.5中列出<int>初始化

jos*_*989 15 c# .net-3.5

我可以初始化一个List<int> like new List<int>{1,2,3,4,5}; 但是List<T>没有一个接受单个参数的构造函数.所以我试图通过调试器运行它,它似乎是调用Add方法.那么编译器如何知道调用哪个方法来添加每个单独的元素.

这可能是一个愚蠢的问题,但我有点困惑.

谢谢

Ita*_*aro 9

每个具有Add和implements IEnumerable方法的类型都可以通过这种方式初始化.编译器只是编译代码,就像使用此Add方法一样.

看看这里

  • 不完全 - 它也必须实现IEnumerable(并且Add方法必须有参数,并且必须有一个可访问的构造函数). (2认同)

Mar*_*ell 8

这是一个集合初始化程序,一个C#3.0语言功能.这个需要:

  • 类型必须实现IEnumerable(虽然这从未用于初始化)
  • 该类型必须至少有一个Add方法

它只是Add为每个术语调用方法.如果Add接受多个值(例如字典),也可以使用元组.每个术语是{key,value}:

new Dictionary<int,string> {{1,"abc"},{2,"def"}};
Run Code Online (Sandbox Code Playgroud)

有关将其用于定制类型的示例:

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


thi*_*eek 6

看看这个方法.

    public void CreateList()
    {
        List<int> list = new List<int> { 1, 2, 3, 4, 5 };
    }
Run Code Online (Sandbox Code Playgroud)

编译之后,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
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它只是一个语法糖,编译器通过连续调用Add()来替换初始化.


Mit*_*eat 5

new List{ 1, 2, 3, 4, 5 }只是句法“糖”。在幕后,它会简单地Add为每个项目调用方法。