2009-04-15 39 views
46

En C#, puedo inicializar una lista con la siguiente sintaxis.Inicialización de una lista genérica en C#

List<int> intList= new List<int>() { 1, 2, 3 }; 

me gustaría saber cómo funciona esa sintaxis {}, y si tiene un nombre. Hay un constructor que toma un IEnumerable, puede llamar eso.

List<int> intList= new List<int>(new int[]{ 1, 2, 3 }); 

que parece más "estándar". Cuando deconstruo el constructor predeterminado para la Lista, solo veo

this._items = Array.Empty; 

Me gustaría poder hacer esto.

CustomClass abc = new CustomClass() {1, 2, 3}; 

Y poder utilizar la lista 1, 2, 3. ¿Como funciona esto?

actualización

Jon Skeet respondió

Está llamando al constructor sin parámetros , y luego llamar Añadir:

> List<int> tmp = new List<int>(); 
> tmp.Add(1); tmp.Add(2); tmp.Add(3); 
> List<int> intList = tmp; 

entiendo lo que es lo hace. Quiero saber cómo. ¿Cómo sabe esa sintaxis para llamar al método Agregar?

actualización

lo sé, cómo cliché para aceptar una respuesta Jon Skeet. Pero, el ejemplo con las cuerdas y los puntos es increíble. También una página muy útil es de MSDN:

Respuesta

64

Esto se llama un inicializador de colección . Está llamando al constructor sin parámetros, y luego llamar Añadir:

List<int> tmp = new List<int>(); 
tmp.Add(1); 
tmp.Add(2); 
tmp.Add(3); 
List<int> intList = tmp; 

Los requisitos para el tipo son:

  • Implementa IEnumerable
  • Tiene sobrecargas de Add que son apropiados para los tipos de argumentos que suministro. Puede suministrar argumentos múltiples entre llaves, en cuyo caso el compilador busca un método Add con múltiples parámetros.

Por ejemplo:

public class DummyCollection : IEnumerable 
{ 
    IEnumerator IEnumerable.GetEnumerator() 
    { 
     throw new InvalidOperationException("Not a real collection!"); 
    } 

    public void Add(string x) 
    { 
     Console.WriteLine("Called Add(string)"); 
    } 

    public void Add(int x, int y) 
    { 
     Console.WriteLine("Called Add(int, int)"); 
    } 
} 

continuación, puede utilizar:

DummyCollection foo = new DummyCollection 
{ 
    "Hi", 
    "There", 
    { 1, 2 } 
}; 

(Por supuesto, normalmente te gustaría su colección para implementar adecuadamente IEnumerable ...)

+0

Qué vergüenza los argumentos fueron al revés, pero se corrigieron ahora :) –

+0

Entonces, ¿por qué le importa que el tipo sea enumerable? no parece agregar nada más que hacer que C# sea más consciente de .NET, similar a IDisposable ... me hace preguntarme por qué foreach requiere SOLO una firma compatible, y no interfaces. Pensé que la idea era que C# no sería específicamente vinculado a un 'lang' – meandmycode

+2

@meandmycode: foreach no está vinculado a IEnumerable porque pre-genéricos no había otra manera de exponer un iterador sin boxeo. Con genéricos, estoy seguro de que se habría * solo * confiado en IEnumerable . (Continuación) –

1

Creo que es un acceso directo al método .Add. Sin embargo, nunca intenté anularlo, así que no sé si es posible.

+0

Es posible, intente implementar un IDictionary –

0

Por lo que a mí respecta, la adición de elementos a través de la inicialización de objetos busca un método Agregar. Entonces, como List < int> tendrá void Add (int), funcionará.

para usarlo en su clase, sólo tiene que añadir

class CustomClass { 
    public void Add(int num) { 
     // Your code here 
    } 
} 

Su clase debe implementar IEnumerable, como Hallgrim señaló.

4

Se llaman collection initializers (también vea here), y la forma en que funcionan es buscando un método Add() que pueda hacer sus pujas. Llama al Add() para cada uno de los enteros que tiene en sus llaves.

La búsqueda del método Add() es pura magia del compilador. Está codificado para encontrar un método de ese nombre.

+0

No está seguro de dónde obtuvo la palabra "predeterminada" a partir de allí; son solo "inicializadores de recopilación". –

+0

Bastante, lo cambié. – mquander

0

De hecho, es utilizando el método .Add. Lo que significa que está llamando al .Add por cada artículo entre corchetes dentro del constructor.

Cuestiones relacionadas