Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Nota
Este artigo abrange tipos de referência anuláveis. Você também pode declarar tipos de valor anuláveis.
Podes usar tipos de referência nullable em código que está num contexto consciente de nullable. Tipos de referência anuláveis, os avisos de análise estática nula e o operador de perdão nula são recursos de linguagem opcionais. Todos são desativados por padrão. Controlas um contexto anulável ao nível do projeto usando definições de build, ou no código usando pragmas.
A referência da linguagem C# documenta a versão mais recentemente lançada da linguagem C#. Contém também documentação inicial para funcionalidades em pré-visualizações públicas para o próximo lançamento linguístico.
A documentação identifica qualquer funcionalidade introduzida pela primeira vez nas últimas três versões da língua ou em pré-visualizações públicas atuais.
Sugestão
Para saber quando uma funcionalidade foi introduzida pela primeira vez em C#, consulte o artigo sobre o histórico de versões da linguagem C#.
Importante
Todos os modelos de projeto habilitam o contexto anulável para o projeto. Projetos criados com modelos anteriores não incluem esse elemento e esses recursos estão desativados, a menos que você os habilite no arquivo de projeto ou use pragmas.
Em um contexto consciente anulável:
- Deve inicializar uma variável de um tipo
Tde referência com um valor não nulo, e nunca poderá atribuir um valor que possa sernull. - Podes inicializar uma variável de um tipo
T?de referência comnullou atribuirnull, mas deves compará-lanullantes de desreferenciar. - Quando se aplica o operador de perdão nulo a uma variável
mdo tipoT?, como emm!, a variável é considerada não nula.
O compilador impõe as distinções entre um tipo T de referência não anulável e um tipo T? de referência anulável usando as regras anteriores. Uma variável do tipo T e uma variável do tipo T? são do mesmo tipo .NET. O exemplo a seguir declara uma cadeia de caracteres não anulável e uma cadeia de caracteres anulável e, em seguida, usa o operador de perdão nula para atribuir um valor a uma cadeia de caracteres não anulável:
string notNull = "Hello";
string? nullable = default;
notNull = nullable!; // null forgiveness
As variáveis notNull e nullable ambas usam o String tipo. Como os tipos não anuláveis e anuláveis usam ambos o mesmo tipo, não se pode usar um tipo de referência anulável em vários locais. Em geral, não podes usar um tipo de referência anulável como classe base ou interface implementada. Não podes usar um tipo de referência anulável em nenhuma expressão de criação de objetos ou teste de tipos. Não podes usar um tipo de referência anulável como tipo de expressão de acesso membro. Os exemplos a seguir mostram essas construções:
public MyClass : System.Object? // not allowed
{
}
var nullEmpty = System.String?.Empty; // Not allowed
var maybeObject = new object?(); // Not allowed
try
{
if (thing is string? nullableString) // not allowed
Console.WriteLine(nullableString);
} catch (Exception? e) // Not Allowed
{
Console.WriteLine("error");
}
Referências anuláveis e análise estática
Os exemplos na seção anterior ilustram a natureza dos tipos de referência anuláveis. Os tipos de referência anuláveis não são novos tipos de classe, mas sim anotações em tipos de referência existentes. O compilador usa essas anotações para ajudá-lo a encontrar possíveis erros de referência nula em seu código. Não há diferença de tempo de execução entre um tipo de referência não anulável e um tipo de referência anulável. O compilador não adiciona nenhuma verificação de tempo de execução para tipos de referência não anuláveis. Os benefícios estão na análise em tempo de compilação. O compilador gera avisos que ajudam você a encontrar e corrigir possíveis erros nulos em seu código. Você declara sua intenção e o compilador avisa quando seu código viola essa intenção.
Importante
As anotações de referência anuláveis não introduzem alterações de comportamento, mas outras bibliotecas podem usar reflexão para produzir comportamentos diferentes em tempo de execução para tipos de referência nuláveis e não anuláveis. Notavelmente, o Entity Framework Core lê atributos anuláveis. Ele interpreta uma referência anulável como um valor opcional e uma referência não anulável como um valor necessário.
Em um contexto habilitado anulável, o compilador executa análise estática em variáveis de qualquer tipo de referência, nulas e não anuláveis. O compilador rastreia o estado nulo de cada variável de referência como não-nulo ou talvez-nulo. O estado padrão de uma referência não anulável não é nulo. O estado padrão de uma referência anulável é talvez-nulo.
Os tipos de referência não anuláveis devem ser sempre seguros para cancelar a referência porque seu estado nulo não é nulo. Para impor essa regra, o compilador emite avisos se um tipo de referência não anulável não for inicializado com um valor não nulo. Deve atribuir variáveis locais onde as declara. A cada campo deve ser atribuído um valor não-nulo , em um inicializador de campo ou em cada construtor. O compilador emite avisos quando uma referência não anulável é atribuída a uma referência cujo estado é talvez-nulo. Geralmente, uma referência não anulável não é nula e não são emitidos avisos quando se desreferenciam essas variáveis.
Nota
Se você atribuir uma expressão maybe-null a um tipo de referência não anulável, o compilador gerará um aviso. Em seguida, o compilador gera avisos para essa variável até que ela seja atribuída a uma expressão não-nula .
Podes inicializar ou atribuir null a tipos de referência anuláveis. Portanto, a análise estática deve determinar que uma variável não é nula antes de ser desreferenciada. Se uma referência anulável for determinada como talvez-nula, atribui-la a uma variável de referência não anulável gera um aviso do compilador. A classe a seguir mostra exemplos desses avisos:
public class ProductDescription
{
private string shortDescription;
private string? detailedDescription;
public ProductDescription() // Warning! shortDescription not initialized.
{
}
public ProductDescription(string productDescription) =>
this.shortDescription = productDescription;
public void SetDescriptions(string productDescription, string? details=null)
{
shortDescription = productDescription;
detailedDescription = details;
}
public string GetDescription()
{
if (detailedDescription.Length == 0) // Warning! dereference possible null
{
return shortDescription;
}
else
{
return $"{shortDescription}\n{detailedDescription}";
}
}
public string FullDescription()
{
if (detailedDescription == null)
{
return shortDescription;
}
else if (detailedDescription.Length > 0) // OK, detailedDescription can't be null.
{
return $"{shortDescription}\n{detailedDescription}";
}
return shortDescription;
}
}
O trecho a seguir mostra onde o compilador emite avisos ao usar essa classe:
string shortDescription = default; // Warning! non-nullable set to null;
var product = new ProductDescription(shortDescription); // Warning! static analysis knows shortDescription maybe null.
string description = "widget";
var item = new ProductDescription(description);
item.SetDescriptions(description, "These widgets will do everything.");
Os exemplos anteriores demonstram como a análise estática do compilador determina o estado nulo das variáveis de referência. O compilador aplica regras de linguagem para verificações e atribuições nulas para informar sua análise. O compilador não pode fazer suposições sobre a semântica de métodos ou propriedades. Se você chamar métodos que executam verificações nulas, o compilador não pode saber que esses métodos afetam o estado nulo de uma variável. Pode adicionar atributos às suas APIs para informar o compilador sobre a semântica dos argumentos e valores de retorno. Muitas APIs comuns nas bibliotecas .NET têm esses atributos. Por exemplo, o compilador interpreta corretamente IsNullOrEmpty como uma verificação nula. Para obter mais informações sobre os atributos que se aplicam à análise estática de estado nulo, consulte o artigo sobre Atributos anuláveis.
Definindo o contexto anulável
Podes controlar o contexto nulo de duas formas. Ao nível do projeto, adiciona a <Nullable>enable</Nullable> definição do projeto. Num único ficheiro fonte C#, adiciona-se o #nullable enable pragma para ativar o contexto anulável. Consulte o artigo sobre como definir uma estratégia anulável. Antes do .NET 6, novos projetos usam o padrão, <Nullable>disable</Nullable>. A partir do .NET 6, novos projetos incluem o <Nullable>enable</Nullable> elemento no arquivo de projeto.
Especificação da linguagem C#
Para mais informações, consulte a secção Tipos de referência anuláveis da especificação da linguagem C#.