Was wird bevorzugt: Nullable<T>.HasValue oder Nullable<T> != null?
Ich immer Nullable<>.HasValue
denn ich mochte die Semantik. Jedoch, vor kurzem arbeitete ich auf einer anderen vorhandenen Codebasis, wo Sie verwendet werden Nullable<> != null
ausschließlich statt.
Gibt es einen Grund, einen über den anderen, oder ist es rein Präferenz?
-
int? a; if (a.HasValue) //...
vs.
-
int? b; if (b != null) //...
Fragte ich eine ähnliche Frage... hab einige gute Antworten:stackoverflow.com/questions/633286/...
Persönlich, würde ich die Verwendung
HasValue
da ich denke, dass Worte eher lesbar als Symbole. Es ist alles bis zu Ihnen, obwohl, und was passt mit Ihrem vorhandenen Stil..HasValue
macht mehr Sinn als es bezeichnet die Art ist vom Typ T?
eher als ein Typ, der null-Werte zulassen, wie strings.
InformationsquelleAutor lc. | 2009-03-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Der compiler ersetzt null Vergleiche mit einem Aufruf
HasValue
, so gibt es keinen wirklichen Unterschied. Nur tun, je mehr lesbar/macht mehr Sinn für Sie und Ihre Kollegen.Wow. Ich hasse diese syntaktischen Zucker.
int? x = null
gibt mir die illusion, dass eine nullable-Instanz ein Verweistyp ist. Aber die Wahrheit ist, dass Nullable<T> ist ein Wert-Typ. Es fühlt ich bekommen würde, eine NullReferenceException zu tun:int? x = null; Use(x.HasValue)
.Wenn der syntaktische Zucker stört Sie, benutzen Sie einfach
Nullable<int>
stattint?
.In den frühen Phasen der Erstellung einer Anwendung, die Sie vielleicht denken, es ist ausreichend, verwenden Sie eine null-Wert geben Sie zum speichern einiger Daten, nur zu erkennen, nach einer Weile, Sie brauchen eine richtige Klasse für Ihren Zweck. Geschrieben haben den original-code zu vergleichen mit null-dann den Vorteil hat, dass Sie nicht brauchen, um suchen/ersetzen-jeder Aufruf HasValue() mit einem null-Vergleich.
Es ist ziemlich albern, sich darüber zu beschweren zu können, eine null-zu-null oder vergleichen Sie es mit null, gegeben, dass die genannt Nullable. Das problem ist, dass die Menschen, diese "Referenz-Typ" mit "kann null sein", aber das ist eine Begriffsverwirrung. Zukunft C# haben null-Referenz-Typen.
InformationsquelleAutor Rex M
Ich lieber
(a != null)
so, dass die syntax entspricht Referenz-Typen.Nullable<>
ist nicht ein Referenz-Typ.Ja, aber die Tatsache, in der Regel ankommt, sehr wenig in dem Punkt sind Sie null Kontrolle.
Es ist nur irreführend, die begrifflich verwechselt. Mit einer konsistenten und gleichbleibende syntax um zwei verschiedene Typen bedeutet nicht, dass Sie vom gleichen Typ. C# nullable-Referenz-Typen (alle Referenz-Typen sind derzeit null-Werte zulässt, aber das wird sich in Zukunft ändern) und nullable value types. Über eine einheitliche syntax für alle nullable-Typen Sinn macht. In keiner Weise bedeutet es, dass nullable-Wertetypen Referenztypen, oder dass null-Werte zulässt Referenz-Datentypen sind Werttypen.
Ich bevorzuge
HasValue
denn es ist mehr lesbar als!= null
InformationsquelleAutor cbp
Habe ich einige der Forschung auf dieser durch die Verwendung verschiedener Methoden, um Werte zuzuweisen, um eine null-int. Hier ist, was passiert, wenn ich nicht verschiedene Dinge. Sollten klären, was Los ist.
Beachten Sie:
Nullable<something>
oder die Kurzformsomething?
ist eine Struktur, für die der compiler scheint zu tun, eine Menge Arbeit, um uns mit null, als ob es eine Klasse.Wie Sie unten sehen werden,
SomeNullable == null
undSomeNullable.HasValue
immer wieder ein erwartet true oder false. Obwohl nicht gezeigt, untenSomeNullable == 3
gilt auch (vorausgesetzt, SomeNullable ist einint?
).Während
SomeNullable.Value
bringt uns zu einem Laufzeitfehler, wenn wir zugewiesennull
zuSomeNullable
. Dies ist in der Tat der einzige Fall, wo nullables könnte uns dazu führen, ein problem, Dank einer Kombination von überladen von Operatoren, überladenobject.Equals(obj)
Methode, und der compiler-Optimierung und monkey business.Hier ist eine Beschreibung von einigen code, den ich lief, und das, was Ausgabe, die es produziert Etiketten:
Ok, probieren wir die nächste Initialisierung Methode:
Alle die gleichen wie vorher. Beachten Sie, dass die Initialisierung mit
int? val = new int?(null);
mit null an den Konstruktor übergeben, hätte erzeugt einen COMPILE time error, da die nullable-Objekt der WERT null ist NICHT zulässig. Es ist nur der wrapper-Objekt selbst, die können gleich null.Ebenfalls, wir würden eine compile-Zeit-Fehler-aus:
nicht zu erwähnen, dass
val.Value
ist ein nur-lese-Eigenschaft sowieso, so können wir nicht einmal so etwas wie:aber wieder, polymorphe überlastet implizite konvertierungsoperatoren lassen Sie uns tun:
Brauchen keine sorgen zu machen polysomthing whatchamacallits obwohl, so lange, wie es richtig funktioniert? 🙂
Sie sind richtig, dass es eine Struktur (nicht die Klasse), aber Sie sind falsch, es überlädt den = = - operator. Wenn Sie
Nullable<X>
im VisualStudio 2013 und F12, wirst du sehen, dass es nur überlastung der Konvertierung zu und vonX
, und dieEquals(object other)
Methode. Allerdings denke ich, dass der = = - operator verwendet, der Methode standardmäßig, also der Effekt ist der gleiche. Ich habe eigentlich Sinne zu aktualisieren, dass diese Antwort auf diese Tatsache für eine Weile jetzt, aber ich bin faul und/oder zu beschäftigt. Dieser Kommentar jetzt zu tun 🙂Ich habe eine schnelle überprüfung durch ildasm, und Sie sind zu Recht über die compiler einige Magische; vergleichen eines Nullable<T> - Objekts auf null gesetzt wird, in der Tat zu übersetzen, um einen Anruf zu HasValue. Interessant!
Tatsächlich, der compiler hat eine Menge Arbeit zu optimieren nullables. Zum Beispiel, wenn Sie einen Wert zuweisen, um eine nullable-Typ, es wird nicht wirklich eine null (z.B.
int? val = 42; val.GetType() == typeof(int)
). Also nicht nur null-Werte zulässt, eine struct, die können gleich null, es auch oft nicht eine null! 😀 Die gleiche Weise, wenn Sie Feld eine null-Wert ist, bist du Boxenint
, nichtint?
- und wenn dieint?
nicht Wert, erhalten Sienull
statt einem boxed nullable-Wert. Im Grunde bedeutet es, es gibt selten einen zusätzlichen overhead von der Verwendung von nullable richtig 🙂Wirklich? Das ist sehr interessant. So was hat die Speicher-profiler sagen Sie über eine null-Feld in einer Klasse? Wie erklären Sie einen Wert-Typ erbt von einem anderen Wert-Typ in C#? Wie erklären Sie sich Ihre eigenen nullable-Typ, verhält sich der gleiche wie .NET nullable-Typ? Seit Wann ist
Null
eine geben .NET? Können Sie zeigen Sie auf den Teil, der in der CLR/C# - Spezifikation, bei der das sagte? Nullables sind gut definiert, der in der CLR-Spezifikation, Ihr Verhalten ist keine "Umsetzung einer Abstraktion" - es ist Vertrag. Aber wenn das beste, was Sie tun können, ist die ad-hominem-Attacken, zu genießen.InformationsquelleAutor Perrin Larson
In VB.Net. Verwenden Sie NICHT "IsNot Nothing", wenn Sie verwenden können ".HasValue". Ich löste eine "Operation destabilisieren könnte die runtime mit" Mittleres Vertrauen Fehler durch Austausch "IsNot " Nichts" mit ".HasValue" auf einem Fleck. Verstehe ich nicht wirklich warum, aber irgend etwas ist passiert, anders als in den compiler. Ich würde davon ausgehen, dass "!= null" in C# haben können dem gleichen Problem.
Ich würde lieber
HasValue
wegen der Lesbarkeit.IsNot Nothing
ist wirklich ein häßlicher Ausdruck (aufgrund der doppelten negation).Nichts" ist keine doppelte Verneinung. "Nichts" ist nicht negativ, es ist eine diskrete Menge, auch außerhalb des Bereichs der Programmierung. "Diese Menge ist nicht nichts." ist grammatisch, die genau das gleiche wie zu sagen "Diese Menge ist nicht gleich null." und weder ist eine doppelte Verneinung.
Es ist nicht so, dass ich nicht wollen, zu widersprechen mit der Abwesenheit von Wahrheit hier, aber komm jetzt. IsNot Nichts ist klar, auch, die übermäßig negative. Warum schreiben Sie nicht etwas positives und klar wie HasValue? Dies ist nicht ein Grammatik-test, es ist die Kodierung, in denen das wichtigste Ziel ist Klarheit.
jmbpiano: ich bin damit einverstanden, es ist nicht die doppelte Verneinung, aber es ist eine einzige Verneinung und das ist ja fast so hässlich und nicht so klar wie eine einfache positive Ausdruck.
InformationsquelleAutor Carter Medlin
Wenn Sie die linq und möchten, dass Ihr code kurz, ich empfehlen immer die Verwendung
!=null
Ist, und deshalb:
Lassen Sie sich vorstellen, wir haben einige Klasse
Foo
mit einem nullable-Doppel - variableSomeDouble
Wenn irgendwo in unserem code, wir wollen alle Foo mit einem nicht-null-SomeDouble Werte aus einer Sammlung von Foo (vorausgesetzt, einige foos in der Sammlung kann null sein), wir am Ende mit mindestens drei Art und Weise zu schreiben, unsere Funktion (wenn wir C# 6) :
Und in dieser Art von situation, die ich empfehlen, gehen immer für die kürzere
foo?.SomeDouble.HasValue
ist eine compile-Zeit-Fehler (nicht ein "Wurf" in meiner Terminologie) in diesem Zusammenhang da der Typbool?
, nicht nurbool
. (Die.Where
Methode will einFunc<Foo, bool>
.) Es ist erlaubt, das zu tun(foo?.SomeDouble).HasValue
natürlich da, der Typ hatbool
. Dies ist, was die erste Zeile ist "übersetzt" werden in die intern vom C# - compiler (zumindest formal).InformationsquelleAutor yan yankelevich
Allgemeine Antwort, und die Faustregel: wenn Sie eine option (z.B. das schreiben von benutzerdefinierten serialisierungsprogramme) zu verarbeiten null-Werte zulässt, die in verschiedenen pipeline als
object
- und die Nutzung Ihrer spezifischen Eigenschaften - tun Sie es und verwenden Sie null-Werte zulässt, spezifischen Eigenschaften.So konsequent denken Sicht
HasValue
bevorzugt werden sollten. Konsistent denken kann Ihnen helfen, besseren code zu schreiben, nicht zu viel Zeit in details.E. g. es zweite Methode wird um ein Vielfaches effektiver (vor allem, weil der Compiler inlining und Boxen, aber immer noch zahlen sind sehr ausdrucksstark):
Benchmark-test:
Benchmark-code:
https://github.com/dotnet/BenchmarkDotNet verwendet wurde
PS. Die Leute sagen, dass der Ratschlag "lieber HasValue, weil der konsequenten denken" ist nicht im Zusammenhang-und sinnlos. Können Sie Vorhersagen, die Leistung dieser?
PPS Menschen weiterhin minus, aber niemand versucht vorherzusagen die Leistung von
CheckNullableGenericImpl
. Und da der compiler wird nicht helfen, Sie ersetzen!=null
mitHasValue
.HasValue
sollte direkt verwendet werden, wenn Sie interessiert sind, in der Leistung.CheckObjectImpl
Boxen der null-Werte zulässt, in eineobject
, in der Erwägung, dassCheckNullableImpl
verwenden, die nicht mit Boxen. Also der Vergleich ist sehr unfare. Nicht nur, es ist kein tarif, ist es auch nutzlos, weil, wie bereits in der akzeptierte Antwort, der compiler schreibt!=
zuHasValue
sowieso.Mein problem ist, dass ich mich über die Qualität der Inhalte auf dieser website. Was du gepostet hast ist entweder irreführend oder falsch. Wenn man versucht, eine Antwort auf die OP-Frage, dann deine Antwort ist flach aus falsch, das ist leicht zu beweisen durch ersetzen des call
CheckObjectImpl
mit seiner Text innerhalbCheckObject
. Aber deine neuesten Kommentare, die zeigen, dass Sie in der Tat noch eine ganz andere Frage in den Sinn, wenn Sie beschlossen, die Antwort auf diese 8 Jahre alte Frage, die Ihre Antwort irreführend, im Kontext der ursprünglichen Frage. Es war nicht das, was der OP war gefragt.Versetzen Sie sich in die Schuhe der nächste Kerl, der googles
what is faster != or HasValue
. Er kommt auf diese Frage, durchsucht deine Antwort, freut sich auf Ihren benchmark und sagt, "Gee, ich werde nie!=
weil es ist eindeutig so viel langsamer!" Das ist eine sehr falsche Schlussfolgerung, die er dann Vorgehen um die Verbreitung. Das ist, warum ich glaube, Ihre Antwort ist schädlich - Sie die Antwort auf eine falsche Frage und so die Pflanzen eine falsche Schlussfolgerung in der ahnungslose Leser. Überlegen Sie, was passiert, wenn Sie ändern IhreCheckNullableImpl
zu auch werdenreturn o != null;
erhalten Sie die gleichen benchmark-Ergebnis.Ich argumentiere mit deiner Antwort. Deine Antwort täuschend echt aussieht, es zeigt den Unterschied zwischen
!=
undHasValue
wenn in der Tat, es zeigt den Unterschied zwischenobject o
undT? o
. Wenn Sie das tun, was ich vorgeschlagen, dass, schreibenCheckNullableImpl
alspublic static bool CheckNullableImpl<T>(T? o) where T: struct { return o != null; }
Sie werden am Ende mit einem benchmark, der zeigt deutlich, dass!=
ist viel langsamer als!=
. Was sollte Sie zu dem Schluss, dass die Frage Ihre Antwort beschreibt, ist nicht etwa!=
vsHasValue
überhaupt.Nachdem er erkannte, dass, könnte man formulieren Sie Ihre Frage um zu erklären, dass der Unterschied in der Tat zwischen
object o
undT? o
, unabhängig davon, ob man benutzt!=
oderHasValue
, so sollte man vermeiden, boxing und unboxing nullable-Werte beim schreiben von benutzerdefinierten serialisiert. Dann wäre es eine absolut richtige und nicht im geringsten irreführende Antwort, aber, nachdem Sie würde haben re-Lesen Sie es, Sie hätte es gelöscht, weil es gewesen wäre, völlig irrelevant für das, was der OP gefragt.InformationsquelleAutor Roman Pokrovskij