| 

.NET C# Java Javascript Exception

2
Letzt habe ich so was gesehen, um ein Array mit Defaultwerten zu initialisieren:
string[] strings = new string[50];
for(int i = 0; i < 50; strings[i++] = "Hallo");

Macht man das so? Ich finde das schlecht lesbar, aber irgendwo cool.
News:
02.06.2011
Nino Schneider 21 1 2
3 Antworten
7
Hallo,

ob man es so macht weiß ich nicht. Ich machs nicht so ;-) weil es eben schwer zu lesen.
Wenns mit Anfangswerten anders als dem Default sein soll dann mach ich es eher so
string[] strings = Enumerable.Repeat("Hallo", 50).ToArray();


mfG Gü
02.06.2011
gfoidl 9,4k 3 5
1
Wenn ich mich recht erinnere, geht das aber erst ab .NET Framework 3.5
Joachim 02.06.2011
Stimmt - LINQ ist Voraussetzung.
gfoidl 02.06.2011
Wenn die Aussagen in
http://stackoverflow.com/questions/136836/c-sharp-array-initialization-with-non-default-value
bzw. in dem von dort verlinkten
http://www.dotnetperls.com/initialize-array
stimmen, dann ist diese Variante um einiges langsamer als die Schleife.
Matthias Hlawatsch 29.09.2012
Das ist klar, denn die for-Schleife greift direkt auf die Elemente zu und kann per Range-Check-Elimination und weitere Techniken voll optimiert werden.
Mit Linq wird ein Iterator erzeugt und durchiteriert und dann erst das Array befüllt. Das ist deutlich mehr Aufwand.

Es stellt sich - je nach Kontext - die Frage ob Leserlichkeit od. Leistung den Vorzug hat. Zu bedenken ist D.E. Knuth mit "premature optimization is the root of all evil".
gfoidl 29.09.2012
@gfoidl, letzter Satz: Prinzipiell bin ich auch ein Anhänger dieser Regel. Im konkreten Fall, und wenn die Benchmarks stimmen (über 1,5s für ein 100-Elemente-Array!), bin ich aber stark am Schwanken, ob der Verzicht auf ein Konstrukt, das so harmlos aussieht, aber in Sachen Performance so gewaltig ins Kontor schlägt, eine "premature optimization" oder doch eher eine Selbstverständlichkeit ist.
Matthias Hlawatsch 30.09.2012
@Matthias: komme bei einem 1.000.000-Elemente-Array nur auf 81 Millisekunden. Die for-Variante in eine stringArray.Initialize("Hallo") ExtensionMethode verpackt kommt auf 33 Millisekunden...
cybere 30.09.2012
3
Ja, denn durch

string[] strings = new string[50];

wird das Array lediglich mit null-Referenzen vorbelegt.

Mit

for(int i = 0; i < 50; strings[i++] = "Hallo");

enthält das Array dann tatsächlich erst string-Objekte.
02.06.2011
Joachim 3,1k 4 9
2
Die Frage ist zwar schon über ein Jahr alt, aber da sie in der Liste nochmal nach oben gerutscht ist, schreibe ich noch was dazu.
Persönlich würde ich bei solchem Code sagen, da war ein C-Hacker am Werk. Eine Schleife mit leerem Body - da muß man beim Lesen wirklich zweimal hinschauen. Mal abgesehen davon, dass ich schon mehrere Code-Richtlinien gesehen habe, in denen auch für einzeilige for- und if-Bodys die geschweiften Klammern vorgeschrieben waren (was ich tendenziell eher gut finde) - dann würde dieses Konstrukt nahezu absurd wirken. Also, auch wenn es kompiliert und funktioniert: ich würde das bei einem Code-Review anstreichen.

Da Microsoft es leider versäumt hat, eine Lösung für einen Custom-Default-Wert ins Framework einzubauen (als statische Methode in der Array-Klasse hätte sich das doch angeboten, bzw. als Überladung von Array.CreateInstance?), bleiben dann meines Wissens nur die Optionen

1.) die "normale" Schleife
string[] strings = new string[50];
for(int i = 0; i < strings.Length; i++)
{
strings[i] = "Hallo";
}

2.) eine eigene Hilfs- bzw. Erweiterungsmethode
3.) die von gfoidl vorschlagene Lösung mit Enumerable.Repeat (und weitere, mMn wiederum schwerer lesbare Ansätze mit LINQ-Mitteln)

Variante 1 hat den Nachteil, dass im Code der beabsichtigte Zweck gegenüber den dafür eingesetzten Mitteln in den Hintergrund tritt. Variante 3 ist da semantisch ausdrucksstärker, aber auch nicht perfekt. Leser, die mit LINQ vertraut sind, können das vermutlich recht schnell erfassen, für andere ist es womöglich noch schwerer verdaulich als die Schleife. Für ein string-Array finde ich es von der Lesbarkeit her ganz ok, für ein int-Array hingegen ziemlich schlecht, weil dann nur für Eingeweihte klar ist, was die Anzahl der Elemente ist und was der Initialisierungs-Wert. Mal abgesehen von der Performance-Problematik. Siehe dazu diesen Beitrag hier (Ich habe das nicht selbst nachgetestet - würde empfehlen selbst zu prüfen, ob die beschriebenen Laufzeit-Unterschiede mit der aktuellen .NET-Version nachvollziehbar sind).

Also ich würde wohl für produktiven Code doch eher Variante 1 hernehmen bzw. Variante 2 (mit der Schleife), wenn ich das Konstrukt mehr als einmal bräuchte.

Schlußendlich: eine ähnliche Frage gab es auch schon bei stackoverflow.
30.09.2012
Matthias Hlawatsch 13,2k 4 9

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH