![]() |
Hoje vamos recordar como tratar com os tipos de referência anuláveis com C#. |
A
linguagem C# é uma linguagem de programação fortemente tipada e com isso temos a
possibilidade de análise estática do código-fonte, ou seja, podemos evitar
algumas exceções que em linguagens não tipadas só perceberíamos em tempo de
execução.
Como a linguagem C# pode trabalhar com tipos anuláveis ou nullable types isso abre uma brecha para alguns tipos especifícos de exceções que podem ocorrer.
Os tipos anuláveis foram introduzidos no C# 2.0 e permitem atribuir nulo ou null a variáveis de tipo de valor. Você pode declarar tipos anuláveis usando Nullable<t> onde T é um tipo. Ex: Nullable<int> i = null; ou int? i = null; |
Vamos considerar o seguinte trecho de código :
Na linha 2 estamos instanciando a classe Cliente e na
linha 3 usamos a propriedade Length para calcular quantos caracteres possui o
nome do cliente.
No entanto note que em nenhum momento atribuimos um valor à propriedade Nome e isso vai lançar uma exceção na linha 3:
A partir do C# 8.0, a verificação de tipo estático anulável foi introduzida, gerando alertas durante a codificação e depuração.
Os tipos de referência anuláveis estão disponíveis a partir do C# 8.0, no código que optou por um contexto com reconhecimento de valor nulo. Os tipos de referência anuláveis, os avisos de análise estática nula e o operador que perdoa nulos(!.) são recursos de linguagem opcionais e todos estão desligados por padrão. Um contexto anulável é controlado no nível do projeto usando configurações de compilação ou no código usando pragmas. |
Para habilitar esta análise estática é necessário declará-la no arquivo .csproj do projeto.A partir do Net 6.0 isso já está habilitado por padrão conforme mostra a figura:
A tag <Nullable> habilita a verificação estática e assim o compilador vai gerar alertas para todos os objetos e tipos anuláveis como mostrado a seguir:
Para inibir os alertas podemos declarar explicitamente que a
propriedade Nome e um tipo anulável alterando o
código para:
string? Nome { get; set; }
Agora o compilador vai emitir alertas quando identificar a possibilidade de exceções devido a valores ausentes em propriedades e objetos anuláveis.
Com a atribuição do valor para a propriedade Nome o alerta do compilador desaparece pois não existe mais a possibilidade de ocorrer a exceção.
Vale a pena destacar que Guid é um tipo de valor,
não um tipo de referência. Tipos de valor não podem ser nulos, a menos que você
os declare como anuláveis explicitamente usando Guid?
(Guid anulável).
Uma forma de tratar com isso é usar o operador de Coealescência Nula:
Cliente
cliente = new();string nome = cliente.Nome ?? "Nome Padrão"; public class Cliente{ public Guid Id { get; set; } public string Nome { get; set; } = string.Empty; } |
Agora estamos inicializando a propriedade Nome com uma string vazia (string.Empty), o que significa que ela nunca será nula, mesmo se você não atribuir um valor a ela explicitamente.
Ou poderíamos usa o operador de acesso condicional :
string
? nome = cliente?.Nome;Além disso temos operador ! que é conhecido como operador de supressão de anulação (null-forgiving operator).
Ele indica ao compilador que você está
ciente de um possível valor nulo e que, ainda assim, deseja acessar ou chamar
membros desse valor sem a geração de alertas ou erros relacionados a nulidade.
Ao usar o operador ! em uma expressão, você está basicamente dizendo ao
compilador para confiar em você e permitir que você acesse o valor, mesmo que
ele possa ser nulo.
Cliente
cliente = new(); string nome = cliente!.Nome;public class Cliente{ public Guid Id { get; set; } public string Nome { get; set; } = string.Empty; } |
No exemplo acima, o
operador ! é usado para suprimir qualquer aviso de possível valor
nulo associado a cliente. Se você tem certeza de que cliente não será nulo
neste contexto específico, o operador ! pode ser usado para evitar warnings
relacionados a nulidade.
No entanto, é importante usar esse operador com cautela. Se você estiver errado e cliente for realmente nulo, você pode encontrar uma exceção de referência nula em tempo de execução.
E estamos conversados...
"Ai dos que são sábios a seus próprios olhos, e prudentes diante de si mesmos!"
Isaías 5:21
Referências: