! : operatore (null-forgiving) (Riferimenti per C#)

L'operatore postfix unario ! è l'operatore null-forgiving o null-suppression. In un contesto di annotazione nullablesi usa l'operatore null-forgiving per eliminare tutti gli avvisi nullable per l'espressione precedente. L'operatore prefisso unario ! è l'operatore di negazione logica . L'operatore null-forgiving non ha alcun effetto in fase di esecuzione. Influisce solo sull'analisi statica del flusso del compilatore modificando lo stato Null dell'espressione. In fase di esecuzione, l'espressione x! restituisce il risultato dell'espressione sottostante x.

Per altre informazioni sulla funzionalità dei tipi di riferimento nullable, vedere Tipi riferimento Nullable.

Esempi

Uno dei casi d'uso dell'operatore null-forgiving consiste nella verifica della logica di convalida degli argomenti. Si consideri ad esempio la classe seguente:

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

    public string Name { get; }
}

Usando il framework di test MSTest, è possibile creare il test seguente per la logica di convalida nel costruttore:

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

Senza l'operatore null-forgiving, il compilatore genera l'avviso seguente per il codice precedente: Warning CS8625: Cannot convert null literal to non-nullable reference type. Usando l'operatore null-forgiving, si informa il compilatore che il passaggio di null è previsto e non deve essere avvisato.

È anche possibile usare l'operatore null-forgiving quando si sa con certezza che un'espressione non può essere null ma il compilatore non riesce a riconoscerlo. Nell'esempio seguente, se il metodo IsValid restituisce true, il relativo argomento non è null ed è possibile dereferenziarlo in modo sicuro:

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;

Senza l'operatore null-forgiving, il compilatore genera l'avviso seguente per il codice p.Name: Warning CS8602: Dereference of a possibly null reference.

Se è possibile modificare il metodo IsValid, è possibile usare l'attributo NotNullWhen per informare il compilatore che un argomento del metodo IsValid non può essere null quando il metodo restituisce true:

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;

Nell'esempio precedente non è necessario usare l'operatore null-forgiving perché il compilatore dispone di informazioni sufficienti per scoprire che p non può essere null all'interno dell'istruzione if. Per altre informazioni sugli attributi che consentono di fornire informazioni aggiuntive sullo stato Null di una variabile, vedere Aggiornare le API con gli attributi per definire le aspettative null.

Specifiche del linguaggio C#

Per altre informazioni, vedere la sezione L'operatore null-forgiving nella bozza della specifica dei tipi di riferimento nullable.

Vedi anche