Pontos Principais
- A alteração das versões do C# requer a modificação direta do arquivo do projeto.
- A ativação global do Nullable Reference Types só pode ser feita com um novo formato de projeto.
- A nulidade pode ser alterada por um arquivo ou por uma linha, quando necessário.
- Use atributos de nulidade para evitar verificações nulas desnecessárias.
- Use o pacote Nullable ao focar em plataformas mais antigas.
Embora partes do C# 8 nunca sejam suportadas no .NET Framework, os Nullable Reference Types podem ser ativados se soubermos alguns truques.
Habilitando o C# 8
A primeira etapa é garantir que estejamos usando o Visual Studio 2019 versão 16.3 ou superior.
Em seguida, precisamos configurar o projeto para o C# 8. Se estivermos acostumados a trabalhar com o Visual Studio, talvez espere alterar de maneira simples a configuração de um projeto. Infelizmente, isso não funciona mais.
Under the new rules, the default version of C# is determined by which framework you are targeting. Only .NET Core 3.0 and .NET Standard 2.1 get C# 8, everything else starts with C# 7.3.
Sob as novas regras, a versão padrão do C# é determinada por qual framework estamos direcionando. Somente o .NET Core 3.0 e o .NET Standard 2.1 possuem o C# 8, o restante começa com o C# 7.3.
Podemos solucionar isso, editando o arquivo do projeto. Vamos abrir o arquivo .csproj do projeto e adicionar esta linha dentro do PropertyGroup.
<LangVersion>8.0</LangVersion>
Se estivermos usando um formato de projeto moderno, podemos abri-lo clicando duas vezes no projeto no Solution Explorer. Podemos reconhecer esse formato porque a raiz do arquivo XML é parecida com esta:
<Project Sdk="Microsoft.NET.Sdk">
Se estivermos usando o formato do projeto legado, podemos editá-lo diretamente, mas será um pouco mais complicado. Uma opção é fechar o Visual Studio e usar o bloco de notas ou algum editor de texto. Como alternativa, podemos instalar o Power Commands do Visual Studio, que adiciona um comando "Edit Project File". Para referência, a raiz do arquivo XML será mais ou menos assim:
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
Habilitando Nullable Reference Types:
A próxima etapa é ativar o recurso de Nullable Reference Types. Se estivermos usando o formato moderno do projeto, poderemos fazer isso globalmente adicionando a seguinte linha logo após a versão da linguagem.
<Nullable>enable</Nullable>
Se estivermos usando o formato de projeto legado, essa alteração não irá funcionar. Não iremos ver o erro, pois o compilador simplesmente ignora a configuração. Então, precisamos ativá-lo arquivo por arquivo. Para fazer isso, vamos adicionar a diretiva anulável no topo de cada arquivo.
#nullable enable
Esse jeito também funcionará nos projetos modernos, se desejarmos ativar o recurso gradualmente.
Atributos de nulidade
Há uma variedade de atributos usados para ajustar o comportamento do verificador nulo. Para explicar o funcionamento, consideremos a função abaixo:
bool TryGet(int key, out Customer? customer)
Está implícito que, se essa função retornar verdadeira, o parâmetro do cliente não será nulo. Por outro lado, se a função retornar falso, o cliente será nulo.
Mas isso não faz parte da assinatura, portanto, se usarmos a função como está, sempre precisaremos de uma verificação no Customer. A solução alternativa é adicionar um atributo que explique o comportamento:
bool TryGet(int key, [NotNullWhen(true)] out Customer? customer)
Da perspectiva do compilador, a linha mostra que o Customer nunca será nulo se um valor verdadeiro for retornado. Isso não diz nada sobre o que acontece se um valor falso retornar, mas já é o suficiente para resolver o problema de assinatura.
Em um artigo intitulado Try out Nullable Reference Types, Phillip Carter descreve os vários atributos em detalhes.
- Condicionais de pós-condições (Conditional postconditions): MaybeNotNullWhen(bool), NotNullWhen(bool)
- Dependências de nulidade (Dependent null-ness): NotNullIfNotNull
- Fluxo: DoesNotReturn, DoesNotReturnIf(bool)
- Pós-condicionais: MaybeNull, NotNull
- Pré-condiconais: AllowNull, DisallowNull
Atributos de nulidade em projetos mais antigos
Os tributos precisam ser definidos para que os utilizemos. Se estivermos usando o .NET Standard 2.1 ou o .NET Core 3.0, isso já foi feito automaticamente. Caso contrário, precisamos criá-los como parte do nosso projeto.
A maneira tradicional de lidar com isso seria criar um novo projeto .NET Core 3, e usar o F12 para fazer a engenharia reversa dos atributos desejados. Em seguida, podemos colá-lo no projeto e adicionar detalhes que estiverem ausentes, o que para os atributos levaria apenas alguns minutos.
Uma maneira mais fácil seria instalar o pacote Nullable de Manuel Römer. Isso copiará o arquivo NullableAttributes.cs para nosso projeto, que inclui todos os atributos necessários. Este pacote não possui componente compilado, é apenas o arquivo de código-fonte.
De qualquer forma, verifiquemos se todos os atributos estão marcados como "interno", e não como público. Isso evita colisões com outras bibliotecas que também podem estar portando de volta os atributos.
Leitura adicional (em inglês)
- What's new in C# 8.0
- Try out Nullable Reference Types
- Adapting Projects to Use C# 8 and Nullable Reference Types
Sobre o autor
Jonathan Allen começou a trabalhar em projetos MIS para uma clínica de saúde no final dos anos 90, transformando-os gradualmente de Access e Excel para uma solução corporativa. Depois de passar cinco anos escrevendo sistemas automatizados de negociação para o setor financeiro, se tornou consultor em uma variedade de projetos, incluindo a interface de usuário para um armazém robótico, a camada intermediária de um software de pesquisa sobre câncer e desenvolvendo soluções para as necessidades de big data de uma grande companhia de seguros imobiliários. Em seu tempo livre, gosta de estudar e escrever sobre artes marciais do século XVI.