! NULL-toleranter Operator (C#-Referenz)

Der unäre Postfixoperator ! ist der NULL-tolerante bzw. NULL-Unterdrückungs-Operator. In einem aktivierten Nullable-Anmerkungskontext verwenden Sie den NULL-toleranten Operator, um alle Nullable-Warnungen für den vorherigen Ausdruck zu unterdrücken. Der unäre Präfixoperator ! ist der Operator für logische Negation. Der NULL-tolerante Operator besitzt zur Laufzeit keine Auswirkungen. Er wirkt sich nur auf die statische Flussanalyse des Compilers aus, indem der NULL-Status des Ausdrucks geändert wird. Zur Laufzeit wird Ausdruck x! in das Ergebnis des zugrunde liegenden Ausdrucks x ausgewertet.

Weitere Informationen zum Feature „Nullable-Verweistypen“ finden Sie unter Nullable-Verweistypen.

Beispiele

Einer der Anwendungsfälle des NULL-toleranten Operators besteht darin, die Argumentvalidierungslogik zu testen. Betrachten Sie beispielsweise die folgende Klasse:

#nullable enable
public class Person
{
    public Person(string name) => Name = name ?? throw new ArgumentNullException(nameof(name));

    public string Name { get; }
}

Mit dem MSTest-Testframework können Sie den folgenden Test für die Validierungslogik im Konstruktor erstellen:

[TestMethod, ExpectedException(typeof(ArgumentNullException))]
public void NullNameShouldThrowTest()
{
    var person = new Person(null!);
}

Ohne den NULL-toleranten Operator generiert der Compiler die folgende Warnung für den oben gezeigten Code: Warning CS8625: Cannot convert null literal to non-nullable reference type. Durch die Verwendung des NULL-toleranten Operators informieren Sie den Compiler darüber, dass die Übergabe von null erwartet wird und keine Warnung erfolgen sollte.

Sie können den NULL-toleranten Operator auch verwenden, wenn Sie definitiv wissen, dass ein Ausdruck nicht null sein kann, der Compiler aber nicht in der Lage ist, dies zu erkennen. Wenn die IsValid-Methode im folgenden Beispiel true zurückgibt, ist das Argument nicht null, und Sie können es sicher dereferenzieren:

public static void Main()
{
    Person? p = Find("John");
    if (IsValid(p))
    {
        Console.WriteLine($"Found {p!.Name}");
    }
}

public static bool IsValid(Person? person)
    => person is not null && person.Name is not null;

Ohne den NULL-toleranten Operator generiert der Compiler die folgende Warnung für den p.Name-Code: Warning CS8602: Dereference of a possibly null reference.

Wenn Sie die IsValid-Methode ändern können, können Sie das NotNullWhen-Attribut verwenden, um den Compiler darüber zu informieren, dass ein Argument der IsValid-Methode nicht null sein kann, wenn die Methode true zurückgibt:

public static void Main()
{
    Person? p = Find("John");
    if (IsValid(p))
    {
        Console.WriteLine($"Found {p.Name}");
    }
}

public static bool IsValid([NotNullWhen(true)] Person? person)
    => person is not null && person.Name is not null;

Im vorherigen Beispiel müssen Sie den NULL-toleranten Operator nicht verwenden, da der Compiler über genügend Informationen verfügt, um zu ermitteln, dass p in der if-Anweisung nicht null sein kann. Weitere Informationen zu den Attributen, mit denen Sie zusätzliche Informationen zum NULL-Status einer Variablen bereitstellen können, finden Sie unter Aktualisieren von APIs mit Attributen zum Definieren von NULL-Erwartungen.

C#-Sprachspezifikation

Weitere Informationen finden Sie im Abschnitt Der NULL-tolerante Operator des Entwurfs der Spezifikation von Nullable-Verweistypen.

Siehe auch