2013-08-08 18 views
14

Ho un metodo che contiene N, il numero di oggetti che voglio creare e ho bisogno di restituire un elenco di N oggetti.Creazione di N oggetti e aggiunta a un elenco

Attualmente posso fare questo con un semplice ciclo:

private static IEnumerable<MyObj> Create(int count, string foo) 
    { 
     var myList = new List<MyObj>(); 

     for (var i = 0; i < count; i++) 
     { 
      myList .Add(new MyObj 
       { 
        bar = foo 
       }); 
     } 

     return myList; 
    } 

E mi chiedo se c'è un altro modo, magari con LINQ per creare questa lista.

ho provato:

private static IEnumerable<MyObj> CreatePaxPriceTypes(int count, string foo) 
    { 
     var myList = new List<MyObj>(count); 

     return myList.Select(x => x = new MyObj 
      { 
       bar = foo 
      }); 

    } 

Ma questo sembra per popolare la mia lista.

Ho provato a cambiare la selezione in un foreach ma è lo stesso affare.

Mi sono reso conto che la lista ha la capacità di conteggio e che LINQ non sta trovando alcun elemento per iterare.

 myList.ForEach(x => x = new MyObj 
     { 
      bar = foo 
     }); 

Esiste un operatore LINQ corretto da utilizzare per farlo funzionare? O dovrei limitarmi al loop?

+0

LINQ è uno strumento di query, non dovrebbe essere usato eccessivamente per la creazione di oggetti – Sayse

+1

Gli operatori di Linq come '.Select()' sono destinati esclusivamente per interrogare insiemi e proiettarli nei moduli richiesti; non sono destinati a fare nulla che altera il set originale. Quello che stai cercando di fare con '.Select()' non è raccomandato, sebbene possa essere fatto funzionare. Mi attaccerei al ciclo. – anaximander

+0

questo potrebbe essere di qualche valore: http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx – Default

risposta

30

È possibile utilizzare il Range per creare una sequenza:

return Enumerable.Range(0, count).Select(x => new MyObj { bar = foo }); 

Se si desidera creare un List, dovreste ToList esso.

Attenzione, è (probabilmente) una soluzione non ovvia, quindi non buttare ancora fuori il modo iterativo di creare la lista.

+0

oh interessante, che ne dici del metodo Repeat? fa la stessa cosa? o creerebbe solo un singolo oggetto e creerà un elenco di puntatori per fare riferimento a quell'unico oggetto? – EdmundYeung99

+1

In questo caso particolare, non importa se si tratta di 'Range' o' Repeat', poiché non si utilizza l'oggetto in 'Select'. Ciò che importa è che genera una sequenza con N elementi, che è necessario creare esattamente N nuovi oggetti ... –

3

Si potrebbe creare metodi di supporto generici, in questo modo:

// Func<int, T>: The int parameter will be the index of each element being created. 

public static IEnumerable<T> CreateSequence<T>(Func<int, T> elementCreator, int count) 
{ 
    if (elementCreator == null) 
     throw new ArgumentNullException("elementCreator"); 

    for (int i = 0; i < count; ++i) 
     yield return (elementCreator(i)); 
} 

public static IEnumerable<T> CreateSequence<T>(Func<T> elementCreator, int count) 
{ 
    if (elementCreator == null) 
     throw new ArgumentNullException("elementCreator"); 

    for (int i = 0; i < count; ++i) 
     yield return (elementCreator()); 
} 

Poi li si potrebbe usare in questo modo:

int count = 100; 

var strList = CreateSequence(index => index.ToString(), count).ToList(); 

string foo = "foo"; 
var myList = CreateSequence(() => new MyObj{ Bar = foo }, count).ToList(); 
+0

questo è probabilmente il modo più complesso per il mio caso, ma potrebbe essere più utile agli altri – EdmundYeung99

Problemi correlati