0Pricing
C# Academy · Lektion

Annotationen: ?, !, MaybeNull und NotNull

Verwenden Sie ? für nullable Typen, ! zur Unterdrückung von Nullwarnungen und Attribute wie MaybeNull und NotNullWhen für eine präzise Ablaufanalyse.

Annotationen: ?, !, MaybeNull und NotNull ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C# Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.

Mehr als ? und !: Nullbarkeitsattribute

Die grundlegende ?-Annotation und die Nullprüfung decken die meisten Fälle ab, aber für einige Muster sind ausdrucksstärkere Annotationen erforderlich. Der Namespace System.Diagnostics.CodeAnalysis stellt Attribute bereit, die dem Compiler tiefere Einblicke in den Null-Datenfluss geben.

MaybeNull und NotNull

[MaybeNull] teilt dem Compiler mit, dass ein nicht-nullbarer Rückgabetyp in der Praxis tatsächlich null sein kann, beispielsweise bei einer generischen Methode. [NotNull] garantiert, dass ein nullable Parameter nach dem Aufruf nicht null ist.

using System.Diagnostics.CodeAnalysis;

// [MaybeNull]: return might be null even though T is non-nullable
[return: MaybeNull]
public T Find<T>(int id)
{
    // Returns default(T) which is null for reference types
    return _cache.TryGetValue(id, out var val) ? val : default!;
}

// [NotNull]: after this call, output is guaranteed non-null
public static void EnsureNotNull<T>(
    [NotNull] ref T? value,
    T defaultValue) where T : class
{
    value ??= defaultValue;
}

NotNullWhen: Bedingte Nicht-Nullbarkeit

[NotNullWhen(true)] teilt dem Compiler mit, dass ein out-Parameter nicht null ist, wenn die Methode true zurückgibt. So wird das standardmäßige TryParse-Muster annotiert.

using System.Diagnostics.CodeAnalysis;

public static bool TryParseEmail(
    string? input,
    [NotNullWhen(true)] out string? email)
{
    if (input?.Contains('@') == true)
    {
        email = input.Trim().ToLower();
        return true;
    }
    email = null;
    return false;
}

// Usage — no warning after true check:
if (TryParseEmail(raw, out var email))
    Console.WriteLine(email.Length); // safe — email is non-null here

MaybeNullWhen: Bedingte Nullbarkeit

[MaybeNullWhen(false)] ist das Gegenstück — der Ausgabewert kann null sein, wenn die Methode false zurückgibt. Dies wird bei TryGetValue-Mustern von Dictionaries verwendet.

// This is how Dictionary<K,V>.TryGetValue is annotated:
public bool TryGetValue(
    TKey key,
    [MaybeNullWhen(false)] out TValue value)
{ ... }

// Usage:
if (!dict.TryGetValue("key", out var value))
    return; // early return — value is null in this branch

Console.WriteLine(value.Length); // safe after the guard

AllowNull und DisallowNull

[AllowNull] für eine nicht-nullbare Eigenschaft erlaubt Aufrufern, ihr null zu übergeben, beispielsweise bei einem Setter, der null in eine leere Zeichenfolge umwandelt. [DisallowNull] verbietet null für einen nullable Typ.

public class Config
{
    private string _name = "";

    // Allow setting null (setter converts null -> empty)
    [AllowNull]
    public string Name
    {
        get => _name;
        set => _name = value ?? "";
    }

    // Getter always returns non-null: fine
    // Setter accepts null: [AllowNull] tells compiler that's OK
}

NotNullIfNotNull: Nullbarkeit weitergeben

[NotNullIfNotNull(paramName)] bedeutet: Wenn Parameter X nicht null ist, ist auch der Rückgabewert nicht null. Das ist für Transformationsfunktionen nützlich.

[return: NotNullIfNotNull(nameof(value))]
public static string? Normalize(string? value)
{
    return value?.Trim().ToLower();
}

// Usage:
string  name = "  Alice  ";
string  norm1 = Normalize(name)!; // guaranteed non-null
string? raw   = GetRaw();
string? norm2 = Normalize(raw);   // still nullable (raw might be null)

DoesNotReturn

[DoesNotReturn] kennzeichnet eine Methode, die immer eine Ausnahme auslöst. Der Compiler weiß, dass der Code nach dem Aufruf nicht erreichbar ist, und unterdrückt dadurch unbegründete Nullwarnungen.

using System.Diagnostics.CodeAnalysis;

[DoesNotReturn]
public static void ThrowNotFound(int id)
    => throw new KeyNotFoundException($"Entity {id} not found");

// Usage — no null warning after the call:
var order = _db.Orders.Find(id);
if (order is null) ThrowNotFound(id);

Console.WriteLine(order.Id); // no CS8602 — compiler knows ThrowNotFound threw

MemberNotNull: Nachbedingung für Felder

[MemberNotNull] teilt dem Compiler mit, dass eine Methode garantiert, dass bestimmte Felder nach ihrer Rückkehr nicht null sind. Das ist für Hilfsmethoden zur verzögerten Initialisierung nützlich.

public class DataLoader
{
    private string? _data;

    [MemberNotNull(nameof(_data))]
    private void EnsureLoaded()
    {
        if (_data is null)
            _data = LoadFromFile();
    }

    public string GetData()
    {
        EnsureLoaded();
        return _data; // no CS8603 — compiler knows _data is set
    }
}

Annotationen kombinieren

Attribute können für präzise API-Verträge kombiniert werden. Hier sehen Sie eine Fluent-Guard-Hilfsmethode, die mehrere Attribute kombiniert.

public static class Guard
{
    [return: NotNull]
    public static T NotNull<T>(
        [NotNull][AllowNull] T? value,
        [CallerArgumentExpression(nameof(value))] string? name = null)
        where T : class
    {
        ArgumentNullException.ThrowIfNull(value, name);
        return value;
    }
}

// Usage:
var product = Guard.NotNull(await _repo.FindAsync(id));
Console.WriteLine(product.Name); // no warning

Nulloperatoren: ?. ?? ??=

Der nullbedingte Operator (?.), der Nullkoaleszenzoperator (??) und der Nullkoaleszenz-Zuweisungsoperator (??=) ermöglichen präzisen, null-sicheren Code ohne ausführliche if-Prüfungen.

string? name = GetName();

// ?. safe navigation
int? len = name?.Length;
string? upper = name?.ToUpper().Trim();

// ?? default value
string display = name ?? "Anonymous";

// ??= lazy init
name ??= "Default";

// Chaining
string result = user?.Profile?.DisplayName ?? user?.Name ?? "Guest";

Schnelltest

Was teilt [NotNullWhen(true)] für einen out-Parameter dem Compiler mit?

Rückblick: Nullbarkeitsannotationen

Die wichtigsten Erkenntnisse:

  • [NotNullWhen(true)]: TryParse-Muster — bei Rückgabe von true nicht null
  • [MaybeNull]: Ein nicht-nullbarer Typ kann dennoch null zurückgeben, etwa bei generischen Standardwerten
  • [DoesNotReturn]: Die Methode löst immer eine Ausnahme aus — der Code danach ist nicht erreichbar
  • [MemberNotNull]: Die Methode garantiert, dass Felder nach ihrer Rückkehr gesetzt sind
  • ?., ??, ??=: präzise null-sichere Navigation und Standardwerte

Häufig gestellte Fragen

Ist die Lektion „Annotationen: ?, !, MaybeNull und NotNull“ kostenlos?

Ja — der vollständige Text von „Annotationen: ?, !, MaybeNull und NotNull“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C# Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Annotationen: ?, !, MaybeNull und NotNull“?

Verwenden Sie ? für nullable Typen, ! zur Unterdrückung von Nullwarnungen und Attribute wie MaybeNull und NotNullWhen für eine präzise Ablaufanalyse. Du übst C# Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um C# Academy zu starten?

Keine Vorkenntnisse erforderlich. C# Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „Annotationen: ?, !, MaybeNull und NotNull“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser C# Academy-Lektion Code schreiben und ausführen?

Ja. Jede C# Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. NRT aktivieren und verstehen
  2. Annotationen: ?, !, MaybeNull und NotNull
  3. Null-bedingte und Null-Koaleszenz-Operatoren
  4. Eine Codebasis auf NRT migrieren
← Zurück zu C# Academy