540 Stimmen

Was ist der Unterschied zwischen Nullable<T>.HasValue und Nullable<T> != null?

Ich habe immer Nullable<>.HasValue weil mir die Semantik gefiel. Kürzlich habe ich jedoch an der bestehenden Codebasis eines anderen Unternehmens gearbeitet, das Nullable<> != null stattdessen ausschließlich.

Gibt es einen Grund, das eine dem anderen vorzuziehen, oder ist es eine reine Vorliebe?

  1. int? a; if (a.HasValue) // ...

vs.

  1. int? b; if (b != null) // ...

10 Stimmen

Ich habe eine ähnliche Frage gestellt... und einige gute Antworten erhalten: stackoverflow.com/questions/633286/

3 Stimmen

Persönlich würde ich verwenden HasValue da ich der Meinung bin, dass Wörter besser lesbar sind als Symbole. Es liegt aber ganz an Ihnen und daran, was zu Ihrem Stil passt.

1 Stimmen

.HasValue macht mehr Sinn, da es bedeutet, dass der Typ vom Typ T? statt eines Typs, der nullbar sein kann, wie z. B. Strings.

590voto

Rex M Punkte 138455

Der Compiler ersetzt null Vergleiche mit einem Aufruf zu HasValue Es gibt also keinen wirklichen Unterschied. Machen Sie einfach das, was für Sie und Ihre Kollegen besser lesbar ist bzw. mehr Sinn ergibt.

60voto

cbp Punkte 24483

Ich bevorzuge (a != null) so dass die Syntax mit Referenztypen übereinstimmt.

23voto

Perrin Larson Punkte 541

Ich habe einige Forschung auf diese durch die Verwendung verschiedener Methoden, um Werte zu einem nullable int zuweisen. Hier ist, was passierte, wenn ich verschiedene Dinge tat. Sollte klären, was los ist. Behalten Sie im Hinterkopf: Nullable<something> oder die Kurzform something? ist eine Struktur, für die der Compiler eine Menge Arbeit zu tun scheint, damit wir sie mit null verwenden können, als ob sie eine Klasse wäre.
Wie Sie unten sehen werden, SomeNullable == null y SomeNullable.HasValue wird immer ein erwartetes true oder false zurückgeben. Auch wenn dies im Folgenden nicht gezeigt wird, SomeNullable == 3 ist ebenfalls gültig (vorausgesetzt, SomeNullable ist ein int? ).
Während SomeNullable.Value führt zu einem Laufzeitfehler, wenn wir null a SomeNullable . Dies ist in der Tat der einzige Fall, in dem Nullables uns ein Problem bereiten könnten, dank einer Kombination von überladenen Operatoren, überladenen object.Equals(obj) Methode, Compiler-Optimierung und Affentheater.

Hier ist eine Beschreibung des Codes, den ich ausgeführt habe, und der Ausgabe, die er in Form von Etiketten erzeugt hat:

int? val = null;
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")

Ok, versuchen wir die nächste Initialisierungsmethode:

int? val = new int?();
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")

Alles wie gehabt. Denken Sie daran, dass die Initialisierung mit int? val = new int?(null); mit der Übergabe von null an den Konstruktor hätte zu einem COMPILE-Zeitfehler geführt, da der WERT des nullbaren Objekts nicht nullbar ist. Nur das Wrapper-Objekt selbst kann gleich null sein.

Ebenso würden wir einen Kompilierzeitfehler von erhalten:

int? val = new int?();
val.Value = null;

ganz zu schweigen davon, dass val.Value ist sowieso eine schreibgeschützte Eigenschaft, was bedeutet, dass wir nicht einmal so etwas wie verwenden können:

val.Value = 3;

aber auch hier ermöglichen uns polymorphe überladene implizite Konvertierungsoperatoren dies:

val = 3;

Kein Grund zur Sorge über polysomthing whatchamacallits obwohl, so lange es funktioniert richtig? :)

16voto

Carter Medlin Punkte 11077

Verwenden Sie in VB.Net NICHT IsNot Nothing wenn Sie Folgendes verwenden können .HasValue . Ich habe gerade einen "Operation could destabilize the runtime" Medium trust Fehler gelöst, indem ich ersetzt habe IsNot Nothing con .HasValue an einer Stelle. Ich verstehe nicht wirklich, warum, aber irgendetwas passiert im Compiler anders. Ich würde annehmen, dass != null in C# können das gleiche Problem haben.

0voto

yan yankelevich Punkte 865

Wenn Sie linq verwenden und Ihren Code kurz halten wollen, empfehle ich Ihnen, immer !=null

Und das ist der Grund:

Stellen wir uns vor, wir haben eine Klasse Foo avec un löschbarer Double variabel SomeDouble

public class Foo
{
    public double? SomeDouble;
    //some other properties
}   

Wenn wir irgendwo in unserem Code alle Foo mit einem SomeDouble-Wert, der nicht null ist, aus einer Sammlung von Foo abrufen wollen (unter der Annahme, dass einige Foos in der Sammlung auch null sein können), haben wir am Ende mindestens drei Möglichkeiten, unsere Funktion zu schreiben (wenn wir C# 6 verwenden):

public IEnumerable<Foo> GetNonNullFoosWithSomeDoubleValues(IEnumerable<Foo> foos)
{
     return foos.Where(foo => foo?.SomeDouble != null);
     return foos.Where(foo=>foo?.SomeDouble.HasValue); // compile time error
     return foos.Where(foo=>foo?.SomeDouble.HasValue == true); 
     return foos.Where(foo=>foo != null && foo.SomeDouble.HasValue); //if we don't use C#6
}

Und in solchen Situationen empfehle ich, immer die kürzere Variante zu wählen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X