C# - Tipos de referência anuláveis
 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

 



Isaías 9:6
Porque um menino nos nasceu, um filho se nos deu, e o principado está sobre os seus ombros, e se chamará o seu nome: Maravilhoso, Conselheiro, Deus Forte, Pai da Eternidade, Príncipe da Paz.

Isaías 9:6

Referências:


José Carlos Macoratti