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

时间:2010-05-28 08:28:30

标签: c# .net-3.5

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

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

由于

5 个答案:

答案 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方法完成。