Skip to content

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: null
s = 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 wurde
if (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 ?-Syntax
Nullable<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-Operator
int 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? – kann null sein.
  • Nicht-nullbarer Referenztyp: string – darf niemals null sein (außer bei Umgehung des Systems).

Beispiel:

#nullable enable
string notNullable = "Hallo"; // Darf nicht null sein
string? nullable = null; // Kann null sein
Console.WriteLine(notNullable.Length); // Sicher
if (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:

  1. Global aktivieren: In der .csproj-Datei:

    <Nullable>enable</Nullable>
  2. Lokal aktivieren/deaktivieren: Im Code mit Präprozessor-Direktiven:

    #nullable enable
    string? optionalValue = null;
    #nullable disable
    string normalString = null; // Keine Warnung

Empfehlungen für die Nutzung

  1. Globale Aktivierung bevorzugen: Aktivieren Sie Nullable Reference Types für das gesamte Projekt, um konsistentes Verhalten sicherzustellen.
  2. Präzise Typen verwenden:
    • T für nicht-nullbare Referenztypen.
    • T? für Typen, die null sein können.
  3. null-Prüfung konsequent einsetzen:
    • Verwenden Sie if (value != null) oder den ?.-Operator.
    • Alternativ den Null-Koaleszenz-Operator (??) für Fallback-Werte.
  4. 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.