Der Wert Null
0 != null
Der Wert null
in der Programmierung ist ein besonderer Wert.
Damit ist nicht die Zahl 0 gemeint, sondern das Nichtvorhandensein eines Wertes.
Hat also eine Variable den Wert null
sagt das so viel aus wie “Es gibt zum jetzigen Zeitpunkt keinen Wert für diese Variable”.
Wertedatentypen vs. Referenzdatentypen
C# kennt folgende built-in, also in die Sprache eingebauten, Wertedatentypen:
- Integral Numeric Types
- int
- uint
- long
- ulong
- short
- ushort
- byte
- sbyte
- Floating Point Numeric Types
- float
- double
- decimal
- bool
- char
Zu den Referenzdatentypen zählen vor allem Strings und Arrays, sowie alle Objekte, also alle Werte, die mithilfe einer Klasse erstellt werden.
Verwendung von null
Allen Variablen für Referenzdatentypen, kann der Wert null
zugewiesen werden. Der Standardwert, wenn Variablen nicht initialisiert wurden, ist ebenso null
.
class Song {}
Song s; // Standardwert bei Referenzdatentypen: nulls = null; // Der Wert null kann auch explizit zugewiesen werden.
Song FindSong(string name) { // Suche den Song mit dem Namen in einer Liste // .. foreach (Song s in Songs) { if (found) { // Haben wir den Song gefunden können wir ihn zurückgeben return s; } }
// Wurde der Song nicht in der Liste gefunden können wir null zurückgeben. // Damit zeigen wir dem Aufrufer, dass wir keinen entsprechenden Song kennen. return null;}
// Verwendung:Song foundSong = FindSong("Ode an die Freude");
// Wir können überprüfen ob der Song gefunden wurdeif (foundSong != null) { // wir haben einen Song gefunden}
Wertedatentypen sind nicht nullable
Alle Wertedatentypen können nicht den Wert null enthalten. Sie haben immer einen Wert, sobald die Variable erstellt wurde. Für alle Wertedatentypen gibt es einen Standardwert (meist die Zahl 0).
int i = null; // nicht möglich
Die Klasse Nullable
Es gibt in C# eine eigene Klasse Nullable
, die einen beliebigen Wert aufnehmen kann, egal ob Wertedatentyp, oder Referenzdatentyp.
Da Nullable
eine Klasse ist, können Variablen dieses Typs natürlich wieder null sein.
Damit können auch Wertedatentypen als null gekennzeichnet werden. Meist verwendet man die Klasse Nullable
nicht direkt, weil die Sprache C# ein eingebautes Sprachkonstrukt hat, die uns die Verwendung leichter macht.
int? nullableInt = null; // Nullable Type mit ?-SyntaxNullable<int> anotherNullableInt = 5; // Äquivalent, aber weniger üblich
if (nullableInt.HasValue){ Console.WriteLine($"Wert ist: {nullableInt.Value}");}else{ Console.WriteLine("Kein Wert vorhanden.");}
// Alternative mit Null-Koaleszenz-Operatorint valueOrDefault = nullableInt ?? 0;Console.WriteLine($"Wert oder Standard: {valueOrDefault}");
Nullable und modernes C#
In modernen C#-Versionen (ab C# 8.0) wird die Nullable Reference Types (NRT)-Funktionalität verwendet, um zu kennzeichnen, welche Referenzdatentypen null
sein können und welche nicht. Dies geschieht nicht mit der Nullable<T>
-Klasse (diese ist spezifisch für Werttypen), sondern durch Compilerhinweise und erweiterte Syntax.
Grundlagen von Nullable Reference Types
Mit Nullable Reference Types können Sie explizit angeben, ob ein Referenztyp null
enthalten darf (string?
) oder nicht (string
). Dies hilft, potenzielle NullReferenceExceptions frühzeitig durch Compilerwarnungen zu erkennen.
Syntax
- Nullable Referenztyp:
string?
– kannnull
sein. - Nicht-nullbarer Referenztyp:
string
– darf niemalsnull
sein (außer bei Umgehung des Systems).
Beispiel:
#nullable enable
string notNullable = "Hallo"; // Darf nicht null seinstring? nullable = null; // Kann null sein
Console.WriteLine(notNullable.Length); // Sicherif (nullable != null){ Console.WriteLine(nullable.Length); // Sicher, da geprüft}
#nullable enable
schaltet die Funktion ein, wenn sie im Projekt noch nicht global aktiviert ist.
Compiler-Unterstützung
Der Compiler überprüft den Code, um sicherzustellen, dass null
-Werte nur für Nullable-Typen (T?
) verwendet werden. Verletzungen führen zu Warnungen, aber keine Laufzeitfehler.
Beispiel mit Warnungen:
string notNullable = null; // Compiler-Warnung: "Null wird einer nicht-nullbaren Variable zugewiesen."string? nullable = null; // Kein Problem
Nullable Reference Types in Klassen und Methoden
Verwendung in Klassen:
Sie können Nullable Reference Types in Klassen verwenden, um optionales Verhalten explizit darzustellen.
public class Person{ public string Name { get; set; } = "Unbekannt"; // Nicht-nullbar, Standardwert erforderlich public string? Nickname { get; set; } // Kann null sein}
Verwendung in Methoden:
public void PrintName(string name){ Console.WriteLine(name); // Erwartet, dass `name` nicht null ist}
public void PrintNickname(string? nickname){ if (nickname != null) { Console.WriteLine(nickname); // Sicher } else { Console.WriteLine("Kein Spitzname vorhanden."); }}
Praktische Anwendung
Beispiel: Nullable für optionale Werte in APIs
public class ApiResponse{ public string Status { get; set; } = "Success"; // Muss gesetzt sein public string? ErrorMessage { get; set; } // Nur bei Fehlern}
In diesem Fall stellt ErrorMessage
sicher, dass nur bei Fehlern ein Wert vorhanden ist. Der Compiler erzwingt, dass ErrorMessage
nur geprüft oder verwendet wird, wenn sie nicht null
ist.
Aktivieren und Deaktivieren
Nullable Reference Types können global oder lokal aktiviert/deaktiviert werden:
-
Global aktivieren: In der
.csproj
-Datei:<Nullable>enable</Nullable> -
Lokal aktivieren/deaktivieren: Im Code mit Präprozessor-Direktiven:
#nullable enablestring? optionalValue = null;#nullable disablestring normalString = null; // Keine Warnung
Empfehlungen für die Nutzung
- Globale Aktivierung bevorzugen: Aktivieren Sie Nullable Reference Types für das gesamte Projekt, um konsistentes Verhalten sicherzustellen.
- Präzise Typen verwenden:
T
für nicht-nullbare Referenztypen.T?
für Typen, dienull
sein können.
null
-Prüfung konsequent einsetzen:- Verwenden Sie
if (value != null)
oder den?.
-Operator. - Alternativ den Null-Koaleszenz-Operator (
??
) für Fallback-Werte.
- Verwenden Sie
- Defensive Programmierung: Initialisieren Sie nicht-nullbare Eigenschaften in Konstruktoren oder mit Standardwerten.
Fazit
Mit Nullable Reference Types in C# können Sie klar kennzeichnen, welche Referenztypen null
sein können und welche nicht. Das verbessert die Codequalität und verhindert häufige Fehler wie NullReferenceException
. Das Feature ist besonders nützlich für große Projekte, APIs und Bibliotheken, um klare Vertragsdefinitionen zu erstellen.