C# Nullable-Typen
In C#,int、float、bool、DateTimeetc. sindWerttyp, sie müssen standardmäßig einen Wert haben und können nichtnull:
int a = null; // 编译错误:无法将 null 转换为 int
Nullable-Typenlösen dieses Problem – sie verleihen Werttypen einen zusätzlichen Zustand "kein Wert" (d. h.,null), was in Szenarien, in denen Daten fehlen können, sehr nützlich ist, wie z. B. Datenbankfelder und API-Rückgabewerte.
Die Deklaration ist sehr einfach: Fügen Sie ein?:
int? a = null; // 合法 int? b = 42; // 合法
hierint?JaNullable<int>syntaktischer Zucker (Kurzform), die beiden sind vollständig äquivalent:
Nullable<int> a = null; // 完整写法 int? a = null; // 简写,效果相同
Das folgende Diagramm zeigt, wie Nullable-Typen im Speicher funktionieren – sie verwenden ein zusätzliches Boolean-Flag, um festzuhalten, "ob ein Wert vorhanden ist":
Der Unterschied zwischen dem einzelnen Fragezeichen ? und dem doppelten Fragezeichen ??
Zwei Operatoren im Zusammenhang mit Nullable-Typen in C# werden oft zusammen verwendet, haben aber völlig unterschiedliche Bedeutungen:
| Operatoren | Name | Zweck | Beispiel |
|---|---|---|---|
? |
Nullable-Typ-Modifizierer | Macht Werttypen dazu fähig,null |
int? i = 3;Äquivalent zuNullable<int> i = new Nullable<int>(3); |
?? |
Null-Coalescing-Operator | Wenn die Variablenulleinen Standardwert bereitstellen, wenn |
int result = i ?? 0; |
Ein einfacher Vergleich:
int i; // 普通值类型,默认值为 0,永远不能是 null int? ii; // 可空类型,默认值为 null
Deklaration und Zuweisung von Nullable-Typen
Deklarationssyntax
<data_type>? <variable_name> = null;
Zum Beispiel:
int? age = null; double? temperature = 36.6; bool? isActive = new bool?(); // 显式构造,默认为 null DateTime? birthday = null;
Nullable<T>kann den normalen Bereich seines zugrunde liegenden Werttyps darstellen, plus einennullWert. Zum Beispiel,Nullable<int>kann sein-2,147,483,648auf2,147,483,647jede ganze Zahl dazwischen, odernull。
Vollständiges Beispiel
Beispiel
namespace NullableDemo
{
class Program
{
static void Main(string[] args)
{
// Nullable-Variablen verschiedener Typen deklarieren
int? num1 = null;
int? num2 = 45;
double? num3 = new double?(); // null
double? num4 = 3.14157;
bool? boolVal = new bool?(); // null
// Wert anzeigen (null wird als leerer String angezeigt)
Console.WriteLine($"num1 = {num1 ?? 0}"); // 0
Console.WriteLine($"num2 = {num2 ?? 0}"); // 45
Console.WriteLine($"num3 = {num3 ?? 0.0}"); // 0
Console.WriteLine($"num4 = {num4 ?? 0.0}"); // 3.14157
Console.WriteLine($"boolVal = {boolVal}"); // (leer)
}
}
}
Ausgabeergebnis:
num1 = 0 num2 = 45 num3 = 0 num4 = 3.14157 boolVal =
Nullzusammenfügungsoperator (??)
??Operator wird verwendet, um einenFallback-Standardwertbereitzustellen. Wenn die linke Seite nichtnullWenn er nicht null ist, gibt er den linken Wert zurück; andernfalls gibt er den rechten Wert zurück:
<表达式1> ?? <表达式2>
- if
<表达式1>ist nichtnull, zurückgeben<表达式1>; - andernfalls gibt er zurück
<表达式2>。
Seit C# 8.0 können Sie auch??=(Nullzusammenfügungs-Zuweisungsoperator), nur wenn die VariablenullNur zuweisen, wenn:
int? x = null; x ??= 10; // x 为 null,赋值为 10 x ??= 20; // x 已有值 10,不再赋值
Beispiel
namespace NullableDemo
{
class Program
{
static void Main(string[] args)
{
double? num1 = null;
double? num2 = 3.14157;
// ?? stellt einen Standardwert bereit
double result1 = num1 ?? 5.34; // num1 ist null → gibt 5.34 zurück
double result2 = num2 ?? 5.34; // num2 hat einen Wert → gibt 3.14157 zurück
Console.WriteLine($"num1 ?? 5.34 = {result1}"); // 5.34
Console.WriteLine($"num2 ?? 5.34 = {result2}"); // 3.14157
// Verkettete Verwendung: mehrere alternative Werte angeben
int? a = null;
int? b = null;
int? c = 42;
int value = a ?? b ?? c ?? 0; // Nacheinander versuchen, schließlich 42 erhalten
Console.WriteLine($"a ?? b ?? c ?? 0 = {value}"); // 42
}
}
}
Ausgabeergebnis:
num1 ?? 5.34 = 5.34 num2 ?? 5.34 = 3.14157 a ?? b ?? c ?? 0 = 42
Gängige Eigenschaften und Methoden von Nullable-Typen
| Mitglied | Beschreibung | Beispiel |
|---|---|---|
.HasValue |
Überprüft, ob die Variable einen Wert hat (gibtbool) |
if (num.HasValue) { ... } |
.Value |
Ruft den tatsächlichen Wert ab (wenn ernullLöst eine Ausnahme ausInvalidOperationException) |
int x = num.Value; |
.GetValueOrDefault() |
Den Wert sicher abrufen; wenn ernullStandardwert des Typs zurückgeben (wie z. B.0) |
num.GetValueOrDefault() |
.GetValueOrDefault(T) |
Den Wert sicher abrufen; wenn ernullAngegebenen Standardwert zurückgeben |
num.GetValueOrDefault(100) |
?? |
Null-Coalescing-Operator (syntaktischer Zucker, entsprichtGetValueOrDefault) |
int result = num ?? 100; |
Beispiel
namespace NullableDemo
{
class Program
{
static void Main(string[] args)
{
int? num = null;
// HasValue + Value (traditioneller Ansatz)
if (num.HasValue)
Console.WriteLine($"Wert: {num.Value}");
else
Console.WriteLine("num hat keinen Wert");
// Standardwert sicher abrufen
Console.WriteLine(num.GetValueOrDefault()); // 0
Console.WriteLine(num.GetValueOrDefault(99)); // 99
Console.WriteLine(num ?? 99); // 99 (äquivalente Notation)
// ⚠ Hinweis: Der direkte Zugriff auf .Value löst eine Ausnahme aus
// int x = num.Value; // InvalidOperationException!
}
}
}
Praktische Anwendungsszenarien
Nullable-Typen sind in der realen Entwicklung sehr verbreitet, insbesondere beim Umgang mit potenziell fehlenden Daten:
Datenbankfeldzuordnung
Felder in der Datenbank dürfen seinNULL, Nullable-Typen können genau entsprechen:
| Benutzer-ID | Alter | Ob aktiv |
|---|---|---|
| 1 | 28 | wahr |
| 2 | null | false |
int? age = GetUserAgeFromDB(userId: 2);
// 安全处理 null
string display = age.HasValue
? $"用户年龄:{age.Value}"
: "年龄未知";
// 或者更简洁的写法
string display2 = $"用户年龄:{age ?? 0}";
Optionale Parameter und Konfiguration
// 配置项可能未设置
int? timeout = GetConfigValue("timeout");
int actualTimeout = timeout ?? 30; // 未设置时使用默认值 30 秒
Verkettete Nullprüfungen (C# 6.0+)
// 使用 ?. 运算符安全访问可能为 null 的对象 string? name = user?.Address?.City?.Name; // 如果 user、Address、City 中任何一个为 null,结果就是 null,不会抛异常
Zusammenfassung
| Funktionen | Beispiel | Beschreibung |
|---|---|---|
| Definieren von Nullable-Typen | int? x = null; |
Äquivalent zuNullable<int> |
| Ermitteln, ob ein Wert vorhanden ist | x.HasValue |
returntrueoderfalse |
| Wert abrufen (unsafe) | x.Value |
Wenn esnullLöst eine Ausnahme ausInvalidOperationException |
| Standardwert abrufen | x ?? 0 |
Wenn esnullDen rechtsseitigen Wert zurückgeben |
| Den angegebenen Standardwert abrufen | x.GetValueOrDefault(10) |
Wenn esnull10 zurückgeben |
| Nullzusammenfügungszuweisung | x ??= 10 |
Nur wennxistnullzuweisen, wenn (C# 8.0+) |
| Sicherer Navigationszugriff | user?.Name |
ifuseristnulldann zurückgebennull(C# 6.0+) |
die "Nullable-Verweistypen" von C# 8.0
Ab C# 8.0 wurde ... eingeführt.Nullable-Verweistypensie und die in diesem Artikel vorgestelltenNullable-Werttypensind zwei verschiedene Mechanismen:
| Vergleichspunkt | Nullable-Werttypen | Nullable-Verweistypen |
|---|---|---|
| Beispiel | int? |
string? |
| Zielobjekt | Werttyp (int、bool、structusw.) |
Verweistypen (string、classArrays usw.) |
| Implementierungsansatz | Zur Laufzeit überNullable<T>Struct-Implementierung |
Statische Compileranalyse, ändert das Laufzeitverhalten nicht |
| Standardzustand | existiert schon immer (seit C# 1.0) | Müssen im Projekt aktiviert werden<Nullable>enable</Nullable> |
| Nullprüfung | Verwenden Sie.HasValueEntscheidungsfindung |
Der Compiler gibt Warnungen aus (keine Fehler) |
Weitere ErweiterungenNullable-Verweistypen sind ein Werkzeug zur Prüfung der Kompilierzeitsicherheit — es ändert nicht das Laufzeitverhalten des Programms, aber dort, wo Code möglicherweise
NullReferenceExceptionCompilerwarnungen ausgegeben werden, die Ihnen helfen, potenzielle Probleme während der Entwicklungsphase zu erkennen.