2010-05-28 6 views
15

Puedo inicializar un List<int> like new List<int>{1,2,3,4,5}; Sin embargo, List<T> no tiene un constructor que acepte un solo parámetro. Así que traté de ejecutar esto a través del depurador y parece estar llamando al método Agregar. Entonces, ¿cómo sabe el compilador qué método invocar para agregar cada elemento individual?Lista <int> inicialización en C# 3.5

Esto puede ser una pregunta tonta, pero estoy un poco confundido.

Gracias

Respuesta

9

Cada tipo que tiene el método Añadir e implementa IEnumerable se puede inicializar esta manera. El compilador solo compila su código como si hubiera usado este método Add.

echar un vistazo here

+2

No del todo - tiene que implementar IEnumerable así (y el método Add tiene que tener parámetros, y tiene que ser un constructor accesible). –

+0

que acaba de editar :) olvidó escribirlo en primer lugar :) –

2

new List{ 1, 2, 3, 4, 5 } es sólo 'azúcar' sintáctica. Debajo de las cubiertas, simplemente llamará al método Add para cada artículo.

+2

¿El downvoter por favor deje un comentario. Gracias. –

+0

hmmm, nadie es dueño de downvoting una respuesta correcta. Democracia en el trabajo! –

6

mirada a este método.

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

Después de compilar esto, el MSIL se parece a esto ..

.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 

Como se puede observar, Es sólo un azúcar sintáctico y el compilador reemplaza la inicialización de llamadas consecutivas de Agregar().

8

Este es un inicializador de colección, un C# 3.0 language feature. Se requiere:

  • El tipo debe aplicar IEnumerable (aunque esto nunca se utiliza para la inicialización)
  • El tipo debe tener al menos un Add método

Simplemente llama al método Add para cada término . También puede usar tuplas si el Add acepta valores múltiples, por ejemplo diccionarios. Cada término es entonces {key,value}:

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

Para un ejemplo del uso de esta para un tipo de medida:

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

Como new List<int>{1,2,3,4,5} es la inicialización del campo, yo prefiero pensar que esto funciona a cabo internamente por la magia desde i no puede afectar la forma en que sucede. Llegando a pensar en ello, es probable que define el método por defecto para añadir elementos a la colección de metadatos, donde [] se hace por el índice y las que implantan IList se realizan por el método Add.

+0

At no es "inicialización de matriz": es un tema separado que funciona de manera muy diferente. Y como * sucede * no depende de 'IList.Añadir' tampoco (pero esa es una suposición razonable). –

+0

Quise decir la inicialización de la colección, también esto podría ser útil para el OP http://stackoverflow.com/questions/459652/why-do-c-collection-initializers-work-this-way – Bablo

Cuestiones relacionadas