Was ist das gewünschte Verhalten , wenn v1ist null?
Solomon Ucko
Antworten:
637
Die anderen Antworten sind alle richtig; Ich wollte nur noch eine hinzufügen, die etwas sauberer ist:
v2 = v1 ??default(int);
Jeder Nullable<T>ist implizit in seinen konvertierbar T, vorausgesetzt, dass der gesamte ausgewertete Ausdruck niemals zu einer Nullzuweisung zu einem ValueType führen kann. Der Null-Koaleszenz-Operator ??ist also nur Syntaxzucker für den ternären Operator:
v2 = v1 ==null?default(int): v1;
... was wiederum Syntaxzucker für ein if / else ist:
if(v1==null)
v2 =default(int);else
v2 = v1;
Nullable<T>Ab .NET 4.0 gibt es außerdem eine "GetValueOrDefault ()" - Methode, bei der es sich um einen nullsicheren Getter handelt, der im Grunde die oben gezeigte Null-Koaleszenz ausführt. Dies funktioniert also auch:
Wird default(int)wirklich gebraucht? Was ist los mit einem einfachen 0?
Cole Johnson
4
Es würde für dieses Beispiel funktionieren, aber im allgemeinen Fall wird empfohlen, es defaultgegebenenfalls zu verwenden. Null ist nicht immer als Wert gültig, geschweige denn als Standardwert. Wenn Sie also durch inteinen generischen Wert ersetzen, Tfunktioniert mein Code, während Null dies nicht tut. In einigen zukünftigen Framework-Versionen defaultkann es auch zu einer Überladung kommen. In diesem Fall kann der Standardcode problemlos genutzt werden, während explizite Null- oder Nullzuweisungen geändert werden müssen.
KeithS
5
Dies sollte nach oben steigen: .NET 4.0, Nullable <T> hat ein "GetValueOrDefault ()"
RandomHandle
Vielen Dank, dass Sie zurückgekommen sind, um es mit GetValueOrDefault zu bearbeiten!
CindyH
Möglicherweise möchten Sie mit DateTime vorsichtig sein, wenn Sie die Standardeinstellung verwenden. Dadurch wird möglicherweise das Standarddatum anstelle von leer eingefügt.
Wenn Sie sich nicht sicher sind, ob v1 null enthält, können Sie auch den Null-Coalescing-Operator verwenden, um einen Fallback-Wert festzulegen. ZB v2 = v1 ?? 0;
Arjen
12
Und achten Sie darauf, v1.HasValuezuerst zu überprüfen .
Yuck
3
MSDN sagt, dass dies eine Ausnahme auslösen wird, wenn dies der Fall v1ist null. Meiner Meinung nach ist dies keine richtige Antwort.
Ventiseis
6
@ventiseis Ich würde denken, dass dies ein wünschenswertes Verhalten ist - ich bin überrascht, dass so viele der anderen Antworten in Ordnung sind, eine Null still in 0 umzuwandeln. Wenn Sie einem nicht nullbaren Typ einen nullbaren Typ zuweisen, sollten Sie sich sicher sein, dass Der Wert ist nicht wirklich null. OP sagte nicht "Ich möchte v1 v2 zuweisen, oder 0, wenn v1 null ist", aber das schien jeder anzunehmen
Wenn Sie wissen, dass dies v1einen Wert hat, können Sie die ValueEigenschaft verwenden:
v2 = v1.Value;
Bei Verwendung der GetValueOrDefaultMethode wird der Wert zugewiesen, falls vorhanden, andernfalls der Standardwert für den Typ oder ein von Ihnen angegebener Standardwert:
v2 = v1.GetValueOrDefault();// assigns zero if v1 has no value
v2 = v1.GetValueOrDefault(-1);// assigns -1 if v1 has no value
Mit der HasValueEigenschaft können Sie überprüfen, ob v1ein Wert vorhanden ist:
if(v1.HasValue){
v2 = v1.Value;}
Es gibt auch Sprachunterstützung für die GetValueOrDefault(T)Methode:
Eine einfache Konvertierung zwischen v1und v2ist nicht möglich, da v1sie einen größeren Wertebereich als hat v2. Es ist alles, was v1der nullStaat halten kann . Zum Konvertieren müssen Sie explizit angeben, in welchem Wert intder nullStatus zugeordnet werden soll. Der einfachste Weg, dies zu tun, ist der ??Bediener
v2 = v1 ??0;// maps null of v1 to 0
Dies kann auch in Langform erfolgen
int v2;if(v1.HasValue){
v2 = v1.Value;}else{
v2 =0;}
Abhängig von Ihrem Verwendungskontext können Sie die Mustervergleichsfunktion von C # 7 verwenden:
int? v1 =100;if(v1 isint v2){Console.WriteLine($"I'm not nullable anymore: {v2}");}
BEARBEITEN:
Da einige Leute abstimmen, ohne eine Erklärung zu hinterlassen, möchte ich einige Details hinzufügen, um die Gründe für die Aufnahme als praktikable Lösung zu erläutern.
Mit dem Mustervergleich von C # 7 können wir jetzt den Typ eines Werts überprüfen und implizit umwandeln. Im obigen Snippet wird die if-Bedingung nur übergeben, wenn der in gespeicherte Wert v1typkompatibel mit dem Typ für ist v2, in diesem Fall int. Daraus folgt, dass wenn der Wert für v1ist null, die if-Bedingung fehlschlägt, da null keinem zugewiesen werden kann int. Richtiger nullist kein int.
Ich möchte hervorheben, dass diese Lösung möglicherweise nicht immer die optimale Wahl ist. Ich schlage vor, dass dies vom genauen Verwendungskontext des Entwicklers abhängt. Wenn Sie bereits ein haben int?und dessen Wert nur dann bedingt bearbeiten möchten, wenn der zugewiesene Wert nicht null ist (dies ist das einzige Mal, dass es sicher ist, ein nullbares int in ein reguläres int umzuwandeln, ohne Informationen zu verlieren), dann Pattern Matching ist vielleicht eine der prägnantesten Möglichkeiten, dies zu tun.
Die Notwendigkeit, einen neuen Variablennamen einzuführen, ist bedauerlich. Dies ist jedoch die beste (sicherste) Lösung, wenn kein Standardwert vorhanden ist, da keine Gefahr besteht, dass Ihre HasValueSchecks versehentlich umgestaltet werden.
Minexew
Ich sehe keinen Vorteil dieser Methode gegenüber v1.HasValue als Prüfung und dann v1.Value, um auf den zugrunde liegenden Wert zuzugreifen. Ich würde es nicht ablehnen, aber ich denke, dieses Problem wurde bereits gelöst und eine neue Technik verleiht dem Problem nicht viel Klarheit. Ich habe es auch als 8-9% langsamer bewertet.
Brandon Barkley
Vielen Dank für das Benchmarking, das ist gut zu wissen! Wie auch immer Sie es betrachten, der Unterschied ist bestenfalls marginal (es sei denn, Sie tun dies in einem zeitkritischen Bereich, nehme ich an). Ich halte dies für "prägnanter" oder möglicherweise "idiomatischer", da es sich auf Syntaxzucker stützt, die anstelle von APIs in die Sprache eingebrannt wurden. Es ist ein bisschen subjektiv, aber vielleicht "wartbarer". Obwohl mir dieser Ansatz wirklich besser gefällt, als mich auf einen Standardwert zu verlassen, wie viele andere Antworten vermuten lassen.
Nicholas Miller
3
Es wird Wert zuweisen v1zu , v2wenn es nicht null ist, sonst wird es einen Standardwert als Null nehmen.
Während dieser Code die Frage möglicherweise beantwortet, verbessert die Bereitstellung eines zusätzlichen Kontexts darüber, warum und / oder wie dieser Code die Frage beantwortet, ihren langfristigen Wert.
Bei der Beantwortung einer acht Jahre alten Frage mit fünfzehn vorhandenen Antworten ist es wichtig zu erklären, welchen neuen Aspekt der Frage Ihre Antwort anspricht, und festzustellen, ob sich die Antwort im Laufe der Zeit geändert hat. Nur-Code-Antworten können fast immer durch Hinzufügen einer Erklärung verbessert werden.
v1
istnull
?Antworten:
Die anderen Antworten sind alle richtig; Ich wollte nur noch eine hinzufügen, die etwas sauberer ist:
Jeder
Nullable<T>
ist implizit in seinen konvertierbarT
, vorausgesetzt, dass der gesamte ausgewertete Ausdruck niemals zu einer Nullzuweisung zu einem ValueType führen kann. Der Null-Koaleszenz-Operator??
ist also nur Syntaxzucker für den ternären Operator:... was wiederum Syntaxzucker für ein if / else ist:
Nullable<T>
Ab .NET 4.0 gibt es außerdem eine "GetValueOrDefault ()" - Methode, bei der es sich um einen nullsicheren Getter handelt, der im Grunde die oben gezeigte Null-Koaleszenz ausführt. Dies funktioniert also auch:quelle
default(int)
wirklich gebraucht? Was ist los mit einem einfachen0
?default
gegebenenfalls zu verwenden. Null ist nicht immer als Wert gültig, geschweige denn als Standardwert. Wenn Sie also durchint
einen generischen Wert ersetzen,T
funktioniert mein Code, während Null dies nicht tut. In einigen zukünftigen Framework-Versionendefault
kann es auch zu einer Überladung kommen. In diesem Fall kann der Standardcode problemlos genutzt werden, während explizite Null- oder Nullzuweisungen geändert werden müssen.So was,
quelle
Sie können die Value-Eigenschaft für die Zuweisung verwenden.
quelle
v1.HasValue
zuerst zu überprüfen .v1
istnull
. Meiner Meinung nach ist dies keine richtige Antwort.Alles was Sie brauchen ist..
quelle
Wenn Sie wissen, dass dies
v1
einen Wert hat, können Sie dieValue
Eigenschaft verwenden:Bei Verwendung der
GetValueOrDefault
Methode wird der Wert zugewiesen, falls vorhanden, andernfalls der Standardwert für den Typ oder ein von Ihnen angegebener Standardwert:Mit der
HasValue
Eigenschaft können Sie überprüfen, obv1
ein Wert vorhanden ist:Es gibt auch Sprachunterstützung für die
GetValueOrDefault(T)
Methode:quelle
Sie können dies nicht tun, wenn v1 null ist, aber Sie können dies mit einem Operator überprüfen.
quelle
Ruft den Wert des Objekts ab. Wenn es null ist, wird der Standardwert von int zurückgegeben, der 0 ist.
Beispiel:
quelle
Wenn der Standardwert für einen bestimmten Typ ein akzeptables Ergebnis ist:
Wenn Sie einen anderen Standardwert wünschen, wenn das Ergebnis undefiniert ist:
Wenn Sie nur den Wert zurückgeben möchten (unabhängig davon, ob die Methode fehlgeschlagen ist oder nicht):
.NET 4.7.2.: Gibt
GetValueOrDefault()
den Feldwert ohne Überprüfung zurück.quelle
Für mich ist die beste Lösung die Verwendung einer
GetValueOrDefault()
Methode.quelle
Die Konvertierung von Int nullable in int kann folgendermaßen erfolgen:
quelle
es ist möglich mit
v2 = Convert.ToInt32(v1);
quelle
Du könntest es tun
quelle
Eine einfache Konvertierung zwischen
v1
undv2
ist nicht möglich, dav1
sie einen größeren Wertebereich als hatv2
. Es ist alles, wasv1
dernull
Staat halten kann . Zum Konvertieren müssen Sie explizit angeben, in welchem Wertint
dernull
Status zugeordnet werden soll. Der einfachste Weg, dies zu tun, ist der??
BedienerDies kann auch in Langform erfolgen
quelle
Abhängig von Ihrem Verwendungskontext können Sie die Mustervergleichsfunktion von C # 7 verwenden:
BEARBEITEN:
Da einige Leute abstimmen, ohne eine Erklärung zu hinterlassen, möchte ich einige Details hinzufügen, um die Gründe für die Aufnahme als praktikable Lösung zu erläutern.
Mit dem Mustervergleich von C # 7 können wir jetzt den Typ eines Werts überprüfen und implizit umwandeln. Im obigen Snippet wird die if-Bedingung nur übergeben, wenn der in gespeicherte Wert
v1
typkompatibel mit dem Typ für istv2
, in diesem Fallint
. Daraus folgt, dass wenn der Wert fürv1
istnull
, die if-Bedingung fehlschlägt, da null keinem zugewiesen werden kannint
. Richtigernull
ist keinint
.Ich möchte hervorheben, dass diese Lösung möglicherweise nicht immer die optimale Wahl ist. Ich schlage vor, dass dies vom genauen Verwendungskontext des Entwicklers abhängt. Wenn Sie bereits ein haben
int?
und dessen Wert nur dann bedingt bearbeiten möchten, wenn der zugewiesene Wert nicht null ist (dies ist das einzige Mal, dass es sicher ist, ein nullbares int in ein reguläres int umzuwandeln, ohne Informationen zu verlieren), dann Pattern Matching ist vielleicht eine der prägnantesten Möglichkeiten, dies zu tun.quelle
HasValue
Schecks versehentlich umgestaltet werden.Es wird Wert zuweisen
v1
zu ,v2
wenn es nicht null ist, sonst wird es einen Standardwert als Null nehmen.Oder unten ist die andere Art, es zu schreiben.
quelle
In C # 7.1 und höher kann der Typ mithilfe des
default
Literal anstelle desdefault
Operators abgeleitet werden, sodass er wie folgt geschrieben werden kann:quelle
quelle