Posts
C# 8 - Tipos de Referência Anuláveis
4 de novembro de 2019 • 4 min de leitura

A Microsoft está adicionando uma nova funcionalidade ao C# 8 chamada Tipos de Referência Anuláveis. Que à primeira vista é confuso porque todos os tipos de referência são anuláveis… então como isso é diferente? Daqui para frente, se a funcionalidade estiver habilitada, os tipos de referência são não-anuláveis, a menos que você os marque explicitamente como anuláveis.
Deixe-me explicar.
Tipos de Referência Anuláveis
Quando os Tipos de Referência Anuláveis estão habilitados e o compilador acredita que um tipo de referência tem o potencial de ser nulo, ele te avisa. Você verá mensagens de aviso do Visual Studio:
E avisos de build:
Para remover este aviso, adicione um ponto de interrogação no final do tipo de referência. Por exemplo:
public string StringTest()
{
string? notNull = null;
return notNull;
}
Agora o tipo de referência se comporta como antes do C# 8.
Esta funcionalidade é habilitada adicionando <span class="inline-code"> #nullable enable </span>
no topo de qualquer arquivo C# ou adicionando <span class="inline-code">lt;NullableReferenceTypes>true</NullableReferenceTypes></span>
ao arquivo .csproj. Por padrão não está habilitada, o que é uma coisa boa, pois se estivesse habilitada qualquer base de código existente provavelmente se iluminaria como uma árvore de Natal.
O Debate sobre Null
Por que a Microsoft está adicionando esta funcionalidade agora? Nulls fazem parte da linguagem desde, bem, o início? Honestamente, não sei por quê. Sempre usei nulls, é um fato da vida em C#. Não percebi que não ter nulls era uma opção… Talvez a vida seja melhor sem eles. Vamos descobrir.
Você deve ou não deve usar nulls? Resumi o debate em andamento como eu os entendo.
A Favor
O argumento a favor dos nulls é geralmente que um objeto tem um estado desconhecido. Este estado desconhecido é representado com null. Você vê isso com o tipo de dados bit no SQL Server, que tem 3 valores, null (não definido), 0 e 1. Você também vê isso em UIs, onde às vezes é importante saber se um usuário tocou em um campo ou não. Alguém pode contra-argumentar com, “Em vez de null, por que não criar um tipo de estado desconhecido ou um estado ‘não definido’?” Como isso é diferente de null? Você ainda teria que verificar este estado adicional. Agora você está criando estados desconhecidos para cada instância. Por que não apenas usar null e ter um estado desconhecido global?
Contra
O argumento contra nulls é que é um tipo de dados diferente e deve ser verificado a cada vez que você usa um tipo de referência. O resultado líquido é código como este:
var user = GetUser(username, password);
if(user != null)
{
DoSomethingWithUser(user);
} else
{
SetUserNotFoundErrorMessage()
}
Se o método GetUser retornasse um usuário em todos os casos, incluindo quando o usuário não é encontrado. Se o código nunca retorna null, então é um desperdício se proteger contra isso e idealmente, isso simplifica o código. No entanto, em algum momento, você precisará verificar por um usuário vazio e exibir uma mensagem de erro. Não usar null não remove a necessidade de atender ao caso de negócio de um usuário não encontrado.
Esta Funcionalidade é uma Boa Ideia?
O propósito desta funcionalidade NÃO é eliminar o uso de nulls, mas sim fazer a pergunta: “Existe uma maneira melhor?” E às vezes a resposta é “Não”. Se pudermos eliminar a verificação constante de nulls com um pouco de planejamento antecipado, que por sua vez simplifica nosso código. Estou dentro. A boa notícia é que C# tornou o trabalho com nulls trivial.
Temo que alguns adotem uma postura dogmática e insistam em eliminar nulls em detrimento de um sistema. Isso é uma tarefa inútil, porque nulls são integrais ao C#.
Os Tipos de Referência Anuláveis são uma boa ideia? São, se o resultado final for código mais simples e menos propenso a erros.
Autor: Chuck Conway é especialista em engenharia de software e IA Generativa. Conecte-se com ele nas redes sociais: X (@chuckconway) ou visite-o no YouTube.