2010-05-28 15 views
15

Mogę zainicjować List<int> like new List<int>{1,2,3,4,5}; Jednak List<T> nie ma konstruktora, który akceptuje pojedynczy parametr. Więc próbowałem uruchomić to przez debugger i wydaje się, że wywołanie metody Add. W jaki sposób kompilator wie, którą metodę wywołać, aby dodać każdy poszczególny element.Lista <int> inicjowanie w C# 3.5

To może być głupie pytanie, ale jestem nieco zdezorientowany.

Dzięki

Odpowiedz

9

Każdy typ, który ma metoda implementuje IEnumerable Dodawanie i można zainicjować w ten sposób. Kompilator kompiluje kod tak, jakby używał tej metody dodawania.

spojrzeć here

+2

Niezupełnie - musi implementować IEnumerable (a metoda Add musi mieć parametry i musi być dostępny konstruktor). –

+0

właśnie edytował to :) zapomniałem napisać to na pierwszym miejscu :) –

2

new List{ 1, 2, 3, 4, 5 } jest po prostu syntaktyczne 'cukier'. Pod okładkami po prostu wywołają metodę Add dla każdego przedmiotu.

+2

Czy downvoter proszę zostaw komentarz. Dzięki. –

+0

hmmm, nikt nie ma prawa do otrzymania nieprawidłowej odpowiedzi. Demokracja w pracy! –

6

Spójrz na tę metodę.

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

Po kompilacji tego, MSIL wygląda następująco ..

.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 

Jak można zaobserwować, to po prostu cukier syntaktyczny i kompilator zastępuje intialization przez kolejnych wezwań add().

8

Jest to inicjator kolekcji, C# 3.0 language feature. To wymaga:

  • typ musi wdrożyć IEnumerable (choć nigdy nie jest używany do inicjowania)
  • typ musi mieć co najmniej jedną Add metoda

to po prostu wywołuje metodę Add dla każdego semestru . Możesz także użyć krotek, jeśli Add akceptuje wiele wartości, na przykład słowniki. Każdy termin jest następnie {key,value}:

new Dictionary<int,string> {{1,"abc"},{2,"def"}}; 

Na przykład za pomocą tego dla typu zamówienie:

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(); } 
} 
0

Jak new List<int>{1,2,3,4,5} jest inicjalizacji tablicy, wolę myśleć, że działa to wewnętrznie przez magię odkąd nie może wpłynąć na sposób, w jaki to się dzieje. Zastanawiając się nad tym, prawdopodobnie definiuje domyślną metodę dodawania elementów do kolekcji w metadanych, gdzie [] jest wykonywana przez indeks, a te, które implementują IList, są wykonywane przez metodę Add.

+0

At nie jest "inicjacją macierzy" - jest to osobny temat, który działa bardzo różnie. A ponieważ * dzieje się * to nie polega na "IList.Dodaj 'albo (ale jest to rozsądne przypuszczenie). –

+0

Chciałem powiedzieć, inicjowanie kolekcji, również może to być pomocne dla OP http://stackoverflow.com/questions/459652/why-do-c-collection-initializers-work-this-way – Bablo