2008-09-25 13 views
31

Was ist der einfachste Weg, um ein Array von dynamischen Größe in C# zu initialisieren, die Sie kennen?C# Array-Initialisierung - mit nicht-Standard-Wert

Dies ist das Beste, was ich mit

private bool[] GetPageNumbersToLink(IPagedResult result) 
{ 
    if (result.TotalPages <= 9) 
     return new bool[result.TotalPages + 1].Select(b => true).ToArray(); 

    ... 

Antwort

34

Verwendung Enumerable.Repeat

Enumerable.Repeat(true, result.TotalPages + 1).ToArray() 
+1

Nun, das ist einfach geil! – Rob

+12

Ich denke, Nigel Leistungsvermerk garantiert eine Erwähnung - http://stackoverflow.com/questions/136836/c-array-initialization-with-non-default-value/1051227#1051227 – CrimsonX

+9

Ich kann nicht glauben, dass Leute upvote für etwas, das ist so 'fuzzy' (meiner Meinung nach) und teuer für eine Operation so einfach wie das Füllen eines Arrays. 'var arr = neuer Typ [10]; für (int i = 0; i Aidiakapi

0

Ungeprüfte kommen konnte, aber könnten Sie dies nur tun?

return result.Select(p => true).ToArray(); 

Den "neuen Bool []" Teil überspringen?

+1

nur, wenn IPagedResult: IEnumerable

5

Ich würde dies tatsächlich vorschlagen:

return Enumerable.Range(0, count).Select(x => true).ToArray(); 

diese Weise können Sie nur ein Array zuweisen. Dies ist im Wesentlichen eine prägnante Weise auszudrücken:

var array = new bool[count]; 

for(var i = 0; i < count; i++) { 
    array[i] = true; 
} 

return array; 
+1

oder sogar neue Bool [count ] .Wählen Sie (x => true) .ToArray() – BjartN

+2

Das würde immer noch zwei Arrays zuweisen. –

13

EDIT: als Kommentator wies darauf hin, meine ursprüngliche Implementierung nicht funktionierte. Diese Version funktioniert, ist aber ziemlich unklug und basiert auf einer for-Schleife.

Wenn Sie bereit sind, eine Erweiterungsmethode zu erstellen, können Sie versuchen, diese

public static T[] SetAllValues<T>(this T[] array, T value) where T : struct 
{ 
    for (int i = 0; i < array.Length; i++) 
     array[i] = value; 

    return array; 
} 

und dann wie diese

bool[] tenTrueBoolsInAnArray = new bool[10].SetAllValues(true); 

Als Alternative aufrufen, wenn Sie zufrieden sind mit einer Klasse herumhängen, könnten Sie etwas wie diese versuchen

public static class ArrayOf<T> 
{ 
    public static T[] Create(int size, T initialValue) 
    { 
     T[] array = (T[])Array.CreateInstance(typeof(T), size); 
     for (int i = 0; i < array.Length; i++) 
      array[i] = initialValue; 
     return array; 
    } 
} 

, die Sie wie

bool[] tenTrueBoolsInAnArray = ArrayOf<bool>.Create(10, true); 

aufrufen kann nicht sicher, was ich bevorzugen, obwohl ich Lurv Erweiterungsmethoden Lose und Lose im Allgemeinen tun.

+0

Ich glaube nicht, dass Ihre SetAllValues ​​funktionieren: In Ihrem Lambda-Ausdruck wird x nicht als Referenz übergeben, so dass die Zuweisung eines Werts den Wert im Array nicht ändert. –

+0

Ja, du hast absolut recht. Ich erwähnte, dass ich es nicht wirklich zusammengestellt habe, was diesen eher elementaren Fehler gezeigt hätte. Ich ersetzte die ForEach durch eine einfache Schleife und das funktioniert gut, aber es ist nicht glatt, wie der Fragesteller verlangte. –

+1

Darüber hinaus hat Ihre Erweiterungsmethode eine Signatur, die impliziert, dass sie ein neues Array zurückgibt, aber das ursprüngliche Array ändert und stattdessen zurückgibt. Schlechte Form. –

70

Wenn von 'slickest' Sie schnellste meine, ich habe Angst, dass Enumerable.Repeat 20x langsamer sein kann als ein für Schleife. Siehe http://dotnetperls.com/initialize-array:

Initialize with for loop:    85 ms [much faster] 
Initialize with Enumerable.Repeat: 1645 ms 

So Dotnetguy der SetAllValues ​​() -Methode verwenden.

+11

+1 für die Leistungsnote. – AMissico

1

Viele Male Sie verschiedene Zellen mit unterschiedlichen Werten initialisieren wollen würde:

public static void Init<T>(this T[] arr, Func<int, T> factory) 
{ 
    for (int i = 0; i < arr.Length; i++) 
    { 
     arr[i] = factory(i); 
    } 
} 

oder in der Fabrik Geschmack:

public static T[] GenerateInitializedArray<T>(int size, Func<int, T> factory) 
{ 
    var arr = new T[size]; 
    for (int i = 0; i < arr.Length; i++) 
    { 
     arr[i] = factory(i); 
    } 
    return arr; 
}