C# Nullable einfach erklärt: So vermeidest du NullReferenceExceptions
Nullable-Typen in C# markieren Variablen, die null sein dürfen – und helfen dir, NullReferenceExceptions früh zu erkennen und zu vermeiden.
By Marcel Schmidtpeter 07 Sept 2026
Dein Programm stürzt ab, kurz vor der Präsentation. Die Fehlermeldung: `NullReferenceException: Object reference not set to an instance of an object`. Klassiker - dieser Fehler ist laut Microsoft eine der häufigsten Ausnahmen in C#-Anwendungen überhaupt. Ob in deiner Abschlussprüfung als Fachinformatiker, im Studium oder im ersten Berufsprojekt: Irgendwann triffst du auf `null`. Genau hier hilft C# Nullable - ein Sprachkonzept, das dich Warnungen anzeigen lässt, *bevor* der Fehler zur Laufzeit passiert.
Was ist null überhaupt?
`null` bedeutet in C#: Eine Variable verweist auf kein Objekt. Stell dir eine Parklücke vor - die Lücke existiert, aber es steht kein Auto drin. Wenn du jetzt versuchst, in das "Auto" einzusteigen, kracht es.
string name = null;
Console.WriteLine(name.Length); // NullReferenceException!Der Compiler hat keine Chance einzugreifen, weil `name.Length` syntaktisch korrekt ist. Erst zur Laufzeit fliegt dir die Exception um die Ohren. C# Nullable ändert genau das: Der Compiler warnt dich schon beim Schreiben.
Was sind Nullable-Typen in C#?
Nullable-Typen teilen sich in zwei Welten: Nullable Value Types für Wertetypen und Nullable Reference Types für Verweistypen. Beide markieren mit einem `?`, dass eine Variable `null` sein darf.
Der wichtige Unterschied zuerst: Wertetypen (`int`, `bool`, `double`, `struct`) können normalerweise gar nicht `null` sein - sie haben immer einen Wert. Verweistypen (`string`, Klassen, Arrays) können dagegen seit jeher `null` sein. Genau das ist die Quelle der meisten Exceptions.
Typ | Kann ohne `?` null sein? | Bedeutung von `?` |
`int` | Nein | `int?` = Zahl oder null |
`bool` | Nein | `bool?` = true, false oder null |
`string` | Ja (historisch) | `string?` = Absicht wird dokumentiert |
`Kunde` (Klasse) | Ja (historisch) | `Kunde?` = darf null sein |
Nullable Value Types: `int?` und `Nullable<T>`
`int?` ist die Kurzform von `Nullable<int>` - ein Wrapper, der eine Zahl plus die Information "ist null" enthält. Das brauchst du immer dann, wenn "kein Wert vorhanden" eine echte Information ist: ein `alter`, das nicht angegeben wurde, oder ein Datenbankfeld ohne Eintrag.
int? alter = null;
if (alter.HasValue)
{
Console.WriteLine($"Alter: {alter.Value}");
}
else
{
Console.WriteLine("Kein Alter angegeben");
}
int sicher = alter ?? 0; // ?? = null-coalescing OperatorMerke: Auf ein `int?` darfst du nicht wie auf ein `int` rechnen, ohne vorher `null` abzufangen. `alter + 5` ergibt nämlich selbst wieder `null`, wenn `alter` null ist - kein Fehler, aber oft eine Überraschung.
Nullable Reference Types: Die Compiler-Warnungen
Seit C# 8.0 (2019) gibt es Nullable Reference Types. Die Idee: Wenn du in deinem Projekt `<Nullable>enable</Nullable>` in der `.csproj` setzt, gilt `string` als "definitiv nicht null" und `string?` als "kann null sein". Der Compiler prüft dann deinen Code und warnt bei verdächtigen Stellen.
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>In neuen .NET-Projekten ist das übrigens standardmäßig aktiviert - bei älteren Projekten musst du es selbst einschalten. Die offizielle Dokumentation dazu findest du auf Microsoft Learn.
#nullable enable
string vorname = "Anna"; // nicht null garantiert
string? spitzname = null; // darf null sein
Console.WriteLine(vorname.Length); // ok
Console.WriteLine(spitzname.Length); // Warnung CS8602!Merke: Nullable Reference Types ändern nicht, was zur Laufzeit passiert - sie sind reine Compile-Time-Warnungen. `null` in eine `string`-Variable zu stecken ist weiterhin möglich, der Compiler meckert nur.
Welches Werkzeug gegen null gibt es?
C# bietet dir vier Werkzeuge, die du kennen solltest:
Null-conditional Operator `?.` - greift nur zu, wenn das Objekt nicht null ist, sonst ist das Ergebnis null
Null-coalescing Operator `??` - liefert einen Ersatzwert, wenn links null steht
Null-coalescing Assignment `??=` - weist nur zu, wenn die Variable noch null ist
Pattern Matching `is not null` - der moderne, empfohlene null-Check
Kunde? kunde = FindeKunde(42);
// alt und fehleranfaellig:
if (kunde != null)
{
Console.WriteLine(kunde.Name);
}
// modern und kompakt:
Console.WriteLine(kunde?.Name ?? "Unbekannt");
// ??= : nur setzen, wenn noch null
kunde ??= new Kunde("Gast");Merke: `kunde?.Name` liefert entweder den Namen oder `null` - ganz ohne if-Block und ohne Exception. Die Operatoren lassen sich auch verketten: `kunde?.Adresse?.Strasse` prüft jede Stufe.
Warum ist `is not null` besser als `!= null`? Weil ein Objekt den `!=`-Operator überladen kann und dann unerwartetes Verhalten zeigt - `is not null` umgeht das. Details dazu liefert die C#-Sprachreferenz auf Microsoft Learn.
Praxisbeispiel: Ein kompletter Kundenmanager
Hier ein vollständiges Beispiel, das alle Konzepte zusammenbringt - inklusive einer typischen Methode, die `null` zurückgeben kann:
using System;
using System.Collections.Generic;
public class Kunde
{
public string Name { get; }
public string? Email { get; set; } // optional, darf null sein
public Kunde(string name)
{
Name = name ?? throw new ArgumentNullException(nameof(name));
}
}
public class KundenManager
{
private readonly List<Kunde> kunden = new List<Kunde>();
public void Hinzufuegen(Kunde kunde)
{
kunden.Add(kunde);
}
// Gibt null zurueck, wenn kein Kunde gefunden wurde
public Kunde? FindeNachName(string name)
{
foreach (Kunde k in kunden)
{
if (k.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
{
return k;
}
}
return null; // ehrlich dokumentiert durch Kunde?
}
}
class Program
{
static void Main()
{
var manager = new KundenManager();
manager.Hinzufuegen(new Kunde("Anna") { Email = "anna@example.com" });
Kunde? treffer = manager.FindeNachName("Anna");
Console.WriteLine($"Gefunden: {treffer?.Name ?? "niemand"}");
Console.WriteLine($"Email: {treffer?.Email ?? "keine hinterlegt"}");
}
}Der Rückgabetyp `Kunde?` signalisiert jedem Aufrufer sofort: Hier kann null herauskommen, behandel das. Genau so kombinierst du Nullable mit Konzepten aus C# Generics oder den Grundlagen der OOP-Prinzipien in C#.
Welche 3 Anfängerfehler solltest du vermeiden?
Fehler 1: Der Null-forgiving Operator `!` als Universallösung. Mit `kunde!.Name` sagst du dem Compiler "Ich weiß es besser, kein Warnen bitte". Wenn du falsch liegst, knallt es trotzdem zur Laufzeit. Nutze `!` nur, wenn du die Nicht-Null-Garantie wirklich beweisen kannst.
Fehler 2: `int?` mit `int` verwechseln. Das hier kompiliert nicht:
int? evtlAlter = null;
int alter = evtlAlter; // Fehler CS0266
int alter2 = evtlAlter ?? 0; // so ist es richtigFehler 3: Null-Check nach dem Zugriff statt davor. Klingt banal, passiert aber ständig unter Zeitdruck - erst `name.Length` im Logging verwenden, drei Zeilen später auf null prüfen. Der Compiler mit aktivem Nullable-Kontext fängt genau solche Reihenfolgefehler ab. Das gilt allerdings nicht für Code, den du über `dynamic` oder Reflexion aufrufst - dort bleibt der Compiler blind.
Übungstipp: Bau dir eine null-Falle
Nimm ein eigenes älteres Projekt (oder ein Tutorial-Projekt) und aktiviere `<Nullable>enable</Nullable>`. Kompiliere und zähle die Warnungen. Korrigiere dann jede einzelne: mal fehlt ein `?`, mal ein `??`, mal ein echter Check. Nach einer Stunde hast du mehr über null-Sicherheit gelernt als durch zehn Artikel lesen - und ein Gefühl dafür, welche Stellen in deinem Code wackelig sind.
FAQ: Häufige Fragen zu C# Nullable
Was ist der Unterschied zwischen `string` und `string?`?
`string` bedeutet bei aktivem Nullable-Kontext "darf nicht null sein", `string?` bedeutet "darf null sein". Ohne aktivierten Kontext ist das nur Dokumentation ohne Prüfung.
Seit wann gibt es Nullable Reference Types?
Seit C# 8.0 im Jahr 2019. Seit .NET 6 (2021) sind sie in neuen Projektvorlagen standardmäßig aktiviert.
Verhindert Nullable die NullReferenceException komplett?
Nein. Es sind Compiler-Warnungen, keine Laufzeit-Garantie. Mit `!`, Legacy-Bibliotheken oder deaktiviertem Kontext kannst du weiterhin Exceptions bekommen - die Wahrscheinlichkeit sinkt aber drastisch.
Was macht der `??`-Operator?
Der Null-coalescing Operator liefert den rechts stehenden Wert, wenn links `null` steht: `name ?? "Gast"` ergibt "Gast", wenn name null ist.
Wann benutze ich `int?` statt `int` mit Defaultwert?
Wenn "kein Wert" eine eigene Bedeutung hat - etwa ein nicht angegebenes Geburtsjahr. Ein Defaultwert wie 0 wäre irreführend, weil 0 ein gültiges (wenn auch unrealistisches) Alter wäre.
Fazit
`null` wirst du in deiner C#-Laufbahn nicht loswerden - aber du kannst den Kampf dagegen gewinnen. Mit C# Nullable in Kombination aus aktiviertem Nullable-Kontext, ehrlichen `?`-Annotationen und den Operatoren `?.`, `??` und `is not null` verwandelst du die berüchtigte `NullReferenceException` von einem Laufzeit-Überraschungsei in einen Compile-Zeit-Hinweis. Genau dieses Detail trennt Anfängercode von professionellem Code - und genau danach fragen Prüfer und Tech-Leads gern.
Wenn du bei C#, OOP oder der Vorbereitung auf deine IHK-Abschlussprüfung Unterstützung brauchst: Schau dir die individuelle IT-Nachhilfe bei study-it.education an. Dort erklären wir dir solche Konzepte Schritt für Schritt - angepasst an dein Tempo, ob Azubi, Student oder Quereinsteiger.
Need someone to walk through this with you?
Instead of re-reading: 30 min with a senior dev.
Book a free first chat →
Nullable-Typen in C# markieren Variablen, die null sein dürfen – und helfen dir, NullReferenceExceptions früh zu erkennen und zu vermeiden.
marcel.schmidtpeter@study-it.education →More reading
C# LINQ filtern und transformieren: Einfach erklärt mit Beispielen
LINQ macht Datenfilterung in C# kinderleicht: Mit Where, Select & Co. filterst und transformierst du Listen in wenigen Zeilen – hier lernst du wie!
C# Lambda Expression einfach erklärt: Syntax & Beispiele
Lambda-Ausdrücke in C# verständlich erklärt: Syntax, Func & Action sowie praxisnahe Beispiele für Azubis, Studenten und Berufseinsteiger.
C# Generics einfach erklärt: Typparameter & generische Klassen
Generics in C# einfach erklärt: Typparameter, generische Klassen und Methoden – ideal für Azubis, Studenten und Berufseinsteiger.