! Operador (null-forgiving) (referência C#)
O operador postfix !
unário é o operador null-forgiving, ou null-suppression. Em um contexto de anotação anulável habilitado, você usa o operador de tolerância nula 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 de tolerância nula 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 x
subjacente.
Para obter mais informações sobre o recurso de tipos de referência anuláveis, consulte Tipos de referência anuláveis.
Exemplos
Um dos casos de uso do operador de tolerância nula é 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 null-forpering, 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 null-forpering, você informa ao compilador que a passagem null
é esperada e não deve ser avisada sobre.
Você também pode usar o operador null-forgiving quando você definitivamente sabe que uma expressão não pode ser null
, mas o compilador não consegue reconhecer isso. No exemplo a seguir, se o IsValid
método retornar true
, seu argumento não null
é e você pode desreferenciar 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 null-forper, o compilador gera o seguinte aviso para o p.Name
código: Warning CS8602: Dereference of a possibly null reference
.
Se você pode modificar o IsValid
método, você pode usar o atributo NotNullWhen para informar o compilador que um argumento do IsValid
método não pode ser null
quando o método retorna 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 null-forgiving porque o compilador tem informações suficientes para descobrir que p
não pode estar null
dentro da if
instrução. Para obter mais informações sobre os atributos que permitem fornecer informações adicionais sobre o estado nulo de uma variável, consulte Atualizar APIs com atributos para definir expectativas nulas.
Especificação da linguagem C#
Para obter mais informações, consulte a seção O operador de tolerância nula do rascunho da especificação de tipos de referência anuláveis.