2012-11-25 8 views
7

Obecnie używam coś takiego zbudować listę 10 obiektów:Jak mogę użyć linq do zainicjowania tablicy powtarzających się elementów?

myList = (from _ in Enumerable.Range(0, 10) select new MyObject {...}).toList() 

ta opiera się mój Pythona tła, gdzie będę pisać:

myList = [MyObject(...) for _ in range(10)] 

Należy pamiętać, że Chcę, aby moja lista zawierała 10 wystąpień mojego obiektu, a nie to samo wystąpienie 10 razy.

Czy to nadal rozsądny sposób robienia rzeczy w języku C#? Czy jest to koszt w porównaniu do prostej pętli for?

+0

Czy używasz wartości Zakres gdzieś w MyObject, czy po prostu potrzebujesz dowolnych obiektów? – Tilak

+0

@ Tilak: Obiekty arbitralne (stąd podkreślenie) – Eric

+0

Skrót IMO dla pętli jest nieznacznie lepszy (czytelność/wydajność) niż kwerenda LINQ. – Tilak

Odpowiedz

4

Osobiście uważam, że Enumerable.Repeat brakuje przeciążenia. Poręczny dodatek byłoby coś takiego:

public static class EnumerableEx 
{ 
    public static IEnumerable<T> Repeat<T>(int amt, Func<T> producer) 
    { 
     for(var i = 0; i < amt; ++i) 
     { 
      yield return producer(); 
     } 
    } 
} 

więc można

EnumerableEx.Repeat(10,() => new object()) //.ToList() 
+0

Przeciążenie nie spowodowałoby jej przecięcia - nie byłbyś w stanie stworzyć iteracji funkcji powtarzanej 10 razy. – Eric

+0

Zdrap to - możesz rozróżnić dwa przypadki według typu zwrotu. – Eric

1

Można spróbować:

Enumerable.Range(0, 1000).Select(x => new MyObject()).ToArray(); 
8

Fluent API wygląda trochę bardziej czytelne w tym przypadku, ale jego niezbyt łatwo dostrzec intencję twojego kodu:

var list = Enumerable.Range(0, 10).Select(_ => new MyObject()).ToList(); 

Proste jeśli pętla jest szybkie i łatwe do zrozumienia, ale także ukrywa zamiaru - tworząc listę 10 pozycji

List<MyObject> list = new List<MyObject>(); 
for (int i = 0; i < 10; i++) 
    list.Add(new MyObject()); 

Najlepszą rzeczą dla czytelności jest producentem, który opisze swoją intencję

public class Builder<T> 
    where T : new() 
{ 
    public static IList<T> CreateListOfSize(int size) 
    { 
     List<T> list = new List<T>(); 
     for (int i = 0; i < size; i++) 
      list.Add(new T()); 
     return list; 
    } 
} 

Zastosowanie:

var list = Builder<MyObject>.CreateListOfSize(10); 

to rozwiązanie jest tak szybko, jak prostego pętli, a intencją jest bardzo jasne. Również w tym przypadku mamy minimalną ilość kodu do napisania.

+1

Całkiem pewne, że 'Enumerable.Range (0, 10)' daje 11 wartości – Eric

+3

@Eric całkiem pewnym drugim parametrem jest 'count' –

+2

Whoops, stoję poprawiony – Eric

Powiązane problemy