Compartilhar via


! ! (tolerante a nulo) operador (referência do C#)

O operador ! de sufixo unário é o operador tolerante a nulo ou de supressão de nulo. Em um contexto de anotação anulável habilitado, use o operador que permite valor nulo para suprimir todos os avisos anuláveis para a expressão anterior. O operador ! de prefixo unário é o operador de negação lógica. O operador tolerante a nulo não tem efeito em tempo de execução. Ele afeta apenas a análise de fluxo estático do compilador alterando o estado nulo da expressão. Em tempo de execução, a expressão x! é avaliada como o resultado da expressão xsubjacente.

Para obter mais informações sobre o recurso de tipos de referência que permitem valor nulo, consulte Tipos de referência que permitem valor nulo.

A linguagem C# faz referência a documentos da versão mais recentemente lançada da linguagem C#. Ele também contém a documentação inicial para funcionalidades em pré-visualizações públicas para o próximo lançamento do idioma.

A documentação identifica qualquer recurso introduzido pela primeira vez nas três últimas versões do idioma ou nas versões prévias públicas atuais.

Dica

Para descobrir quando um recurso foi introduzido pela primeira vez em C#, consulte o artigo sobre o histórico de versão da linguagem C#.

Exemplos

Um caso de uso para o operador que permite valor nulo é testar a lógica de validação de argumento. Por exemplo, considere a seguinte classe:

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

    public string Name { get; }
}

Usando a estrutura de teste mstest, você pode criar o seguinte teste para a lógica de validação no construtor:

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

Sem o operador tolerante a nulo, o compilador gera o seguinte aviso para o código anterior: Warning CS8625: Cannot convert null literal to non-nullable reference type. Usando o operador que permite valor nulo, você informa ao compilador que a passagem null é esperada e não deve gerar um aviso.

Você também pode usar o operador que permite valor nulo quando definitivamente sabe que uma expressão não pode ser null , mas o compilador não reconhece isso. No exemplo a seguir, se o método IsValid retornar true, seu argumento não será null e você poderá desreferenciá-lo com segurança:

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;

Sem o operador tolerante a nulo, o compilador gera o seguinte aviso para o código p.Name: Warning CS8602: Dereference of a possibly null reference.

Se você puder modificar o método IsValid, poderá usar o atributo NotNullWhen para informar ao compilador que um argumento do método IsValid não pode ser null quando o método retornar 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;

No exemplo anterior, você não precisa usar o operador de tolerância nula porque o compilador tem informações suficientes para descobrir que p não pode ser null dentro da instrução if. Para obter mais informações sobre os atributos que permitem fornecer informações adicionais sobre o estado nulo de uma variável, consulte As APIs de Atualização com atributos para definir expectativas quanto a nulos.

Especificação da linguagem C#

Para obter mais informações, consulte a seção Operador tolerante a nulo do Rascunho da especificação de tipos de referência que permitem valor nulo.

Confira também