Diese Frage taucht gelegentlich auf, aber ich habe keine zufriedenstellende Antwort gesehen.
Ein typisches Muster ist (Zeile ist eine DataRow ):
if (row["value"] != DBNull.Value)
{
someObject.Member = row["value"];
}
Meine erste Frage ist, welche effizienter ist (ich habe die Bedingung umgedreht):
row["value"] == DBNull.Value; // Or
row["value"] is DBNull; // Or
row["value"].GetType() == typeof(DBNull) // Or... any suggestions?
Dies zeigt an, dass .GetType () schneller sein sollte, aber vielleicht kennt der Compiler ein paar Tricks, die ich nicht kenne?
Zweite Frage: Lohnt es sich, den Wert von row ["value"] zwischenzuspeichern, oder optimiert der Compiler den Indexer trotzdem?
Beispielsweise:
object valueHolder;
if (DBNull.Value == (valueHolder = row["value"])) {}
Anmerkungen:
- Zeile ["Wert"] existiert.
- Ich kenne den Spaltenindex der Spalte nicht (daher die Suche nach Spaltennamen).
- Ich frage speziell nach DBNull und dann nach Zuweisung (nicht nach vorzeitiger Optimierung usw.).
Ich habe einige Szenarien verglichen (Zeit in Sekunden, 10.000.000 Versuche):
row["value"] == DBNull.Value: 00:00:01.5478995
row["value"] is DBNull: 00:00:01.6306578
row["value"].GetType() == typeof(DBNull): 00:00:02.0138757
Object.ReferenceEquals hat die gleiche Leistung wie "=="
Das interessanteste Ergebnis? Wenn Sie den Namen der Spalte von Fall zu Fall nicht übereinstimmen (z. B. "Wert" anstelle von "Wert"), dauert dies ungefähr zehnmal länger (für eine Zeichenfolge):
row["Value"] == DBNull.Value: 00:00:12.2792374
Die Moral der Geschichte scheint zu sein: Wenn Sie eine Spalte nicht anhand ihres Index nachschlagen können, stellen Sie sicher, dass der Spaltenname, den Sie dem Indexer zuführen, genau mit dem Namen der DataColumn übereinstimmt.
Das Zwischenspeichern des Werts scheint ebenfalls fast doppelt so schnell zu sein:
No Caching: 00:00:03.0996622
With Caching: 00:00:01.5659920
Die effizienteste Methode scheint also zu sein:
object temp;
string variable;
if (DBNull.Value != (temp = row["value"]))
{
variable = temp.ToString();
}
IDataRecord
Erweiterungen geliebt .