So konvertieren Sie C # nullable int in int

484

Wie konvertiere ich eine Nullable intin eineint ? Angenommen, ich habe 2 Arten von int wie folgt:

int? v1;  
int v2; 

Ich möchte den v1Wert zuweisen v2. v2 = v1;wird einen Fehler verursachen. Wie konvertiere ich v1zu v2?

KentZhou
quelle
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:

v2 = v1.GetValueOrDefault();
KeithS
quelle
4
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.
Ranch Camal
168

So was,

if(v1.HasValue)
   v2=v1.Value
Srinivas Reddy Thatiparthy
quelle
92

Sie können die Value-Eigenschaft für die Zuweisung verwenden.

v2 = v1.Value;
e36M3
quelle
8
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
Michael Mrozek
82

Alles was Sie brauchen ist..

v2= v1.GetValueOrDefault();
der Stern
quelle
49

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:

v2 = v1 ?? -1;
Guffa
quelle
Sie sollten den Wert nicht verwenden, ohne vorher zu überprüfen, ob ein Wert vorhanden ist. Verwenden Sie die ?? Operator stattdessen.
Peter
45

Sie können dies nicht tun, wenn v1 null ist, aber Sie können dies mit einem Operator überprüfen.

v2 = v1 ?? 0;
Arturo Martinez
quelle
28

GetValueOrDefault()

Ruft den Wert des Objekts ab. Wenn es null ist, wird der Standardwert von int zurückgegeben, der 0 ist.

Beispiel:

v2= v1.GetValueOrDefault();

Aniket Sharma
quelle
21

Wenn der Standardwert für einen bestimmten Typ ein akzeptables Ergebnis ist:

if (v1.HasValue)
    v2 = v1.GetValueOrDefault();

Wenn Sie einen anderen Standardwert wünschen, wenn das Ergebnis undefiniert ist:

v2 = v1.GetValueOrDefault(255);    // or any valid value for int in place of 255

Wenn Sie nur den Wert zurückgeben möchten (unabhängig davon, ob die Methode fehlgeschlagen ist oder nicht):

v2 = v1.GetValueOrDefault();


.NET 4.7.2.: Gibt GetValueOrDefault()den Feldwert ohne Überprüfung zurück.

GrzegorzF
quelle
15

Für mich ist die beste Lösung die Verwendung einer GetValueOrDefault()Methode.

v2 = v1.GetValueOrDefault();
Masoud Darvishian
quelle
Dieser war am besten nützlich für mich
Liakat
11

Die Konvertierung von Int nullable in int kann folgendermaßen erfolgen:

v2=(int)v1;
Krishna Shidnekoppa
quelle
9
Wenn v1 null ist, führt dies zu einer InvalidOperationException.
MungeWrath
10

es ist möglich mit v2 = Convert.ToInt32(v1);

Rev.
quelle
Dies funktioniert technisch, aber andere Techniken wie HasValue / Value oder GetValueOrDefault werden viel effizienter ausgeführt.
Brandon Barkley
9

Du könntest es tun

v2 = v1.HasValue ? v1.Value : v2;
Feuerpanda
quelle
9

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;
}
JaredPar
quelle
9

Abhängig von Ihrem Verwendungskontext können Sie die Mustervergleichsfunktion von C # 7 verwenden:

int? v1 = 100;
if (v1 is int 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.

Nicholas Miller
quelle
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.

v2=v1??0

Oder unten ist die andere Art, es zu schreiben.

v2 = v1.HasValue?v1:0
sagar
quelle
-1
 int v2= Int32.Parse(v1.ToString());
mohammad qavizi
quelle
5
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.
Xiawi
1
Es ist besser, die "Best Practice" -Methode zum Auspacken von Optionen zu verwenden, als hinterhältige Tricks zu verwenden. Siehe docs.microsoft.com/en-us/dotnet/csharp/language-reference/… als Referenz
lorg
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.
Jason Aller