Ich stoße oft auf folgenden Code:
if ( items != null)
{
foreach(T item in items)
{
//...
}
}
Grundsätzlich stellt die if
Bedingung sicher, dass der foreach
Block nur ausgeführt wird, wenn er items
nicht null ist. Ich frage mich, ob die if
Bedingung wirklich benötigt wird oder foreach
ob der Fall behandelt wird, wenn items == null
.
Ich meine, kann ich einfach schreiben
foreach(T item in items)
{
//...
}
ohne sich Gedanken darüber zu machen, ob items
null ist oder nicht? Ist der if
Zustand überflüssig? Oder dies hängt von der Art der items
oder vielleicht auf T
so gut?
null
) verallgemeinern die gesamte Schleife zum LCDEnumerable
(wie die Verwendung??
würde ), b) erfordern, dass jedem Projekt eine Erweiterungsmethode hinzugefügt wird, oder c) dass zunächstnull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) vermieden wird (cuznull
bedeutet N / A, während leere Liste bedeutet, dass es anwendbar ist, aber ist Derzeit, na ja , leer !, dh ein Mitarbeiter könnte Provisionen haben, die N / A für Nicht-Verkäufe oder leer für Verkäufe sind, wenn sie keine verdient haben.Antworten:
Sie müssen noch prüfen, ob (items! = Null), sonst erhalten Sie die NullReferenceException. Sie können jedoch Folgendes tun:
Sie können jedoch die Leistung überprüfen. Also bevorzuge ich es immer noch, wenn (items! = Null) zuerst zu haben.
Aufgrund von Erics Lippert-Vorschlag habe ich den Code geändert in:
quelle
IEnumerable<T>
die sich wiederum zu einem Enumerator zu einer Schnittstelle verschlechtert, wodurch die Iteration langsamer wird. Mein Test zeigte eine Verschlechterung des Faktors 5 für die Iteration über ein int-Array.Mit C # 6 können Sie den neuen bedingten Nulloperator zusammen mit
List<T>.ForEach(Action<T>)
(oder Ihrer eigenenIEnumerable<T>.ForEach
Erweiterungsmethode) verwenden.quelle
null
) Verallgemeinerung der gesamten Schleife auf das LCD vonEnumerable
(wie bei Verwendung??
) beinhaltet, b) das Hinzufügen einer Erweiterungsmethode zu jedem Projekt erfordert, oder c ) erfordern zunächst das Vermeiden vonnull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) (cuznull
bedeutet N / A, während leere Liste bedeutet, dass es anwendbar ist, aber derzeit gut leer ist !, dh ein Empl. könnte Provisionen haben, die N / A für Nicht-Verkäufe oder leer für Verkäufe, wenn sie keine verdient haben).items
eher ein GedankeList<T>
als irgendein istIEnumerable<T>
. (Oder haben Sie eine benutzerdefinierte Erweiterungsmethode, von der Sie gesagt haben, dass Sie nicht möchten, dass es sie gibt ...) Außerdem würde ich sagen, dass es sich nicht lohnt, 11 Kommentare hinzuzufügen, die alle im Grunde sagen, dass Ihnen eine bestimmte Antwort gefällt.foreach
. Besonders für eine Liste, die meiner Meinung nach in einefor
Schleife umgewandelt wird.Das eigentliche Mitnehmen hier sollte eine Sequenz sein, die fast nie null sein sollte . Machen Sie es einfach in allen Ihren Programmen zu einer Invariante, dass eine Sequenz niemals null ist, wenn Sie sie haben. Es wird immer als leere Sequenz oder eine andere echte Sequenz initialisiert.
Wenn eine Sequenz niemals null ist, müssen Sie sie natürlich nicht überprüfen.
quelle
null
) verallgemeinern die gesamte Schleife zum LCDEnumerable
(wie die Verwendung??
würde ), b) erfordern, dass jedem Projekt eine Erweiterungsmethode hinzugefügt wird, oder c) dass zunächstnull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) vermieden wird (cuznull
bedeutet N / A, während leere Liste bedeutet, dass es anwendbar ist, aber ist Derzeit, na ja , leer !, dh ein Mitarbeiter könnte Provisionen haben, die N / A für Nicht-Verkäufe oder leer für Verkäufe sind, wenn sie keine verdient haben.Tatsächlich gibt es auf diesem @Connect eine Funktionsanforderung: http://connect.microsoft.com/VisualStudio/feedback/details/93497/foreach-should-check-for-null
Und die Antwort ist ganz logisch:
quelle
Sie könnten es immer mit einer Nullliste testen ... aber das habe ich auf der msdn-Website gefunden
quelle
Es ist nicht überflüssig. Zur Laufzeit werden Elemente in eine IEnumerable umgewandelt und die GetEnumerator-Methode aufgerufen. Dies führt zu einer Dereferenzierung von Elementen, die fehlschlagen
quelle
IEnumerable
und 2) Es ist eine Entwurfsentscheidung, sie werfen zu lassen. C # könnte diesenull
Prüfung leicht einfügen, wenn die Entwickler dies für eine gute Idee halten.Sie können die Nullprüfung in eine Erweiterungsmethode einkapseln und ein Lambda verwenden:
Der Code wird:
If kann noch präziser sein, wenn Sie nur eine Methode aufrufen möchten, die ein Element nimmt und zurückgibt
void
:quelle
Du brauchst das. Beim
foreach
Zugriff auf den Container wird eine Ausnahme angezeigt, um die Iteration anderweitig einzurichten.Unter den Abdeckungen,
foreach
verwendet eine Schnittstelle für die Sammlung Klasse implementiert , um die Iteration durchzuführen. Die generische äquivalente Schnittstelle ist hier .quelle
Der Test ist erforderlich, denn wenn die Auflistung null ist, löst foreach eine NullReferenceException aus. Es ist eigentlich ganz einfach, es auszuprobieren.
quelle
Der zweite wird ein
NullReferenceException
mit der Nachricht werfenObject reference not set to an instance of an object.
quelle
Wie hier erwähnt , müssen Sie überprüfen, ob es nicht null ist.
quelle
In C # 6 können Sie etw wie folgt schreiben:
Es ist im Grunde Vlad Bezdens Lösung, aber mit dem ?? Ausdruck, um immer ein Array zu generieren, das nicht null ist und daher die foreach überlebt, anstatt diese Prüfung in der foreach-Klammer zu haben.
quelle