Was ist der beste Weg, das erste Objekt einer Sammlung zu prüfen und abzurufen?

8

Ich verstehe, dass das etwas trivial ist, aber ...

Was ist der beste Weg, um die Referenz als erstes Element einer Sammlung zu erhalten? Angenommen, die Sammlung enthält Elemente eines Referenztyps.

Codebeispiel 1:

%Vor%

Das obige Beispiel hat zwei separate Aufrufe für die Sammlung, die eine Iteration starten, die abgeschlossen wird, sobald die erste erkannt wird.

Codebeispiel 2:

%Vor%

Das obige Beispiel hat nur einen einzigen Aufruf für die Sammlung, führt aber eine Variable ein, die unnötigerweise in einem weiteren Bereich liegt.

Gibt es Best Practices für dieses Szenario? Gibt es eine bessere Lösung?

    
Luke Baulch 02.03.2011, 00:08
quelle

7 Antworten

6

Ich bevorzuge das zweite Beispiel, weil es im allgemeinen effizienter ist. Es ist möglich, dass diese Sammlung eine Kombination aus vielen verschiedenen verzögerten LINQ-Abfragen ist, so dass selbst das erste Element eine nicht unerhebliche Menge an Arbeit erfordert.

Stellen Sie sich zum Beispiel vor, dass diese Sammlung aus der folgenden LINQ-Abfrage erstellt wird

%Vor%

Um nur das erste Element von collection zu erhalten, ist eine vollständige Sortierung des Inhalts von originalList erforderlich. Diese vollständige Sortierung erfolgt jedes Mal, wenn die Elemente von collection ausgewertet werden.

Die erste Stichprobe bewirkt, dass die potenziell teure Sammlung zweimal ausgewertet wird: über die Methode Any und First . Das zweite Beispiel wertet die Sammlung nur einmal aus, und daher würde ich es über das erste auswählen.

    
JaredPar 02.03.2011, 00:47
quelle
3

Sie könnten eine Erweiterungsmethode wie folgt erstellen:

%Vor%

Dann würden Sie es so verwenden:

%Vor%     
Gabe 02.03.2011 00:54
quelle
2

Die zweite Funktion arbeitet nicht mit nicht nullbaren Wertetypen ( Bearbeiten: wie Sie angenommen haben - das erste Mal nicht) und hat außer der ersten, die eine a hat, keine Alternative Rennzustand. Es gibt zwei Alternativen, die beide geeignet sind - die Auswahl des einen oder anderen hängt davon ab, wie oft Sie eine leere Sequenz erhalten.

Wenn es sich um einen häufigen oder erwarteten Fall handelt, bei dem Sie eine leere Enumeration erhalten, ist die Verwendung einer foreach -Schleife relativ ordentlich:

%Vor%

oder wenn du% break nicht drin haben willst (was verständlich ist):

%Vor%

Wenn es relativ ungewöhnlich ist, dass es leer ist, dann sollte ein try/catch -Block die beste Leistung bringen (da Ausnahmen nur dann teuer sind, wenn sie tatsächlich ausgelöst werden - eine nicht erhobene Ausnahme ist praktisch frei):

%Vor%

Eine dritte Option besteht darin, einen Enumerator direkt zu verwenden, obwohl dieser identisch mit der foreach -Version sein sollte und etwas weniger klar ist:

%Vor%     
Zooba 02.03.2011 00:26
quelle
1

Manchmal benutze ich dieses Muster:

%Vor%

Er initiiert nur eine Iteration (also besser als Code Sample 1) und der Umfang der Variable firstItem ist innerhalb der Klammern begrenzt (also besser als Code Sample 2).

    
linepogl 02.03.2011 00:20
quelle
1

Oder als Erweiterung der Lösung von Gabe, verwenden Sie ein Lambda, damit Sie das if:

fallen lassen können %Vor%

Und benutze es wie:

%Vor%     
Dennis Smit 02.03.2011 01:21
quelle
0

Da alle generischen Collections (dh: vom Typ System. Collections.ObjectModel ) habe das Count -Member wie folgt:

%Vor%

Dies ist sicher, da alle Collections sowohl die Count als auch die Item Eigenschaft besitzen. Es ist auch sehr geradlinig und leicht für andere Programmierer, die Ihren Code lesen, um zu verstehen, was Ihre Absicht ist.

    
Ian Dallas 02.03.2011 01:01
quelle
0

Sie haben einfach einen einfachen Test für den primitiven Typ durchgeführt und sehen so aus, als ob Ihr Codebeispiel # 2 in diesem Fall am schnellsten ist (aktualisiert):

%Vor%

AnyFirst
 NonEmpty: 00: 00: 00.0000262 Sekunden
 EmptySet: 00: 00: 00.0000174 Sekunden

ForLoop
NonEmpty: 00: 00: 00.0000158 Sekunden
EmptySet: 00: 00: 00.0000151 Sekunden

NullCheck
NonEmpty: 00: 00: 00.0000088 Sekunden
EmptySet: 00: 00: 00.0000064 Sekunden

TryGetFirst
NonEmpty: 00: 00: 00.0000177 Sekunden
EmptySet: 00: 00: 00.0000172 Sekunden

    
Luke Hutton 02.03.2011 01:31
quelle

Tags und Links