2009-04-15 6 views
46

In C#, è possibile inizializzare un elenco utilizzando la seguente sintassi.Inizializzazione di un elenco generico in C#

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

Vorrei sapere come funziona che {} sintassi, e se si ha un nome. C'è un costruttore che prende uno IEnumerable, potresti chiamarlo.

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

Sembra più "standard". Quando ho decostruisco il costruttore di default per l'elenco vedo solo

this._items = Array.Empty; 

Vorrei essere in grado di fare questo.

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

Ed essere in grado di utilizzare l'elenco 1, 2, 3. Come funziona?

Aggiornamento

Jon Skeet ha risposto

E 'chiamare il costruttore senza parametri , e quindi chiamando Aggiungi:

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

ho capito che cosa è fa. Voglio sapere come. Come sa questa sintassi chiamare il metodo Add?

Aggiornamento

lo so, come cliché di accettare una risposta Jon Skeet. Ma l'esempio con archi e stringhe è fantastico. Anche una pagina molto utile MSDN è:

risposta

64

Questo è chiamato un collezione inizializzatore. E 'chiamare il costruttore senza parametri, e quindi chiamando Aggiungere:

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

I requisiti per il tipo sono:

  • Implementa IEnumerable
  • Ha sovraccarichi di Add che sono appropriati per i tipi di argomenti che si fornitura. È possibile fornire più argomenti in parentesi graffe, nel qual caso il compilatore cerca un metodo Add con più parametri.

Ad esempio:

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)"); 
    } 
} 

È quindi possibile utilizzare:

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

(Naturalmente, di solito ci si vuole la vostra collezione di implementare correttamente IEnumerable ...)

+0

Vergogna gli argomenti erano il modo sbagliato - ma risolto ora :) –

+0

Quindi, perché è cura che il tipo è enumerabile? non sembra aggiungere altro che rendere C# più consapevole di .NET, simile a IDisposable .. mi chiedo perché foreach richiede JUST una firma compat e non interfacce .. Ho pensato che l'idea fosse così C# non sarebbe specificamente legato a un 'lang' – meandmycode

+2

@meandmycode: foreach non è legato a IEnumerable perché pre-generici non c'era altro modo di esporre un iteratore senza boxe. Con i generici sono sicuro che avrebbe * solo * basato su IEnumerable . (Continua) –

1

Credo sia una scorciatoia per il metodo .Add. Non ho mai provato a sovrascriverlo, quindi, non so se è possibile.

+0

E 'possibile, prova ad implementare un IDictionary –

0

Per quanto mi riguarda, l'aggiunta di elementi tramite l'inizializzazione dell'oggetto ricerca un metodo Aggiungi. Quindi, come l'elenco < int> avrà l'opzione void Add (int), funzionerà.

di usarlo nella classe, è sufficiente aggiungere

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

La classe dovrebbe implementare IEnumerable, come Hallgrim sottolineato.

4

Si chiamano collection initializers (vedi anche here) e il loro modo di lavorare è cercare un metodo Add() che possa fare le loro offerte. Chiama Add() per ciascuno degli interi che hai tra parentesi graffe.

La ricerca del metodo Add() è pura magia del compilatore. È codificato per trovare un metodo con quel nome.

+0

Non sai da dove hai la parola "default" da lì - sono solo "inizializzatori di raccolta". –

+0

Abbastanza giusto, l'ho cambiato. – mquander

0

In realtà utilizzando il metodo .Add. Significa che sta chiamando .Add per ogni elemento tra parentesi all'interno del costruttore.