BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Notícias Futuro do C#: tipos nuláveis

Futuro do C#: tipos nuláveis

Favoritos

Uma das novas propostas para o C# é assumir que todas as variáveis que são passadas por referência sejam não-nuláveis por padrão. Com a nova sintaxe, é preciso indicar explicitamente quando uma referência é nulável, como atualmente é feito para tipos passados por valor.

Assim como tipos passados por valor, T representaria um tipo não-nulável e T? um tipo nulável. O compilador geraria warnings para os seguintes casos:

  • A variável nulável é dereferenciada (isto é, seu valor é utilizado)
  • Uma variável ou parâmetro nulável é atribuído a uma variável não-nulável
  • O uso de cast de T?[] para T[]
  • O uso de cast de T[] para T?[]
  • O valor nulo literal (isto é, a palavra-chave null) é atribuído a uma variável ou parâmetro não-nulável
  • O construtor não atribui valor a todos os campos não-nuláveis

Para os primeiros dois casos, o warning seria omitido se utilizado o operador bang (x!) ou se o compilador conseguir prever que uma checagem para o valor nulo foi feita anteriormente.

Detalhes de implementação

Compiladores em versões anteriores ignorariam as anotações sobre o uso de nulo, então isso não seria um problema. No entanto, deverá existir algum tipo de marcação de assembly para indicar que a biblioteca foi compilada com as anotações ativadas.

Já que tudo isso que foi proposto é tecnicamente uma mudança que quebra compatibilidade, o plano atual é deixar que os desenvolvedores optem por:

  • Warnings para tipos nuláveis
  • Warnings para tipos não-nuláveis
  • Warnings oriundos de anotações de outros arquivos

A proposta continua:

A granularidade das opções de warning sugerem um modelo no qual grandes porções de código podem habilitar ou não os warnings através do uso de pragmas e que o nível de severidade seja escolhido pelo usuário. Além disso, opções por biblioteca ("ignorar as anotações do JSON.NET até estar disposto a encarar seus warnings) podem ser expressadas no código por atributos.

Esse modelo tenta alcançar os seguintes objetivos:

  • Usuários possam adotar a checagem de valores nuláveis gradualmente à medida que desejarem
  • Autores de bibliotecas possam acrescentar anotações sobre os valores nuláveis sem medo de quebrar o uso de seus usuários
  • Apesar disso, que não haja um pesadelo em termos de configuração

Não será possível ter um uma sobrecarga nulável e não-nulável de um mesmo método. Enquanto tecnicamente o CLR possui tal suporte, isso não faz parte do CLS (Common Language Specification). Isso significa que a maioria dos compiladores não entenderiam a sobrecarga. HaloFour explica:

modreq é "não-CLS". modopt não suporta sobrecargas, mas requer um conhecimento específico por parte de todos os compiladores que utilizam-no, já que o modificador deve ser pelo menos copiado para a assinatura da chamada. Ambos quebram compatibilidade com as assinaturas de métodos existentes. Para algo que potencialmente irá proliferar rapidamente para todo o BCL, utilizar modopt pode criar um grande obstáculo.

Generics

Warnings adicionais podem aparecer ao utilizar generics:

  • O uso de cast de C<T> para CC<T?>, a não ser que o parâmetro do tipo T seja covariante (out)
  • O uso de cast de CC<T?> para C<T>, a não ser que o parâmetro do tipo T seja contravariante (in)
  • Utilizar CC<T?> quando o parâmetro do tipo T é restrito a não ser nulo

Utilizar “class” restringiria o tipo genérico a tipos que não aceitam nulo. “class?” permitiria nulos. A proposta continua:

Se um parâmetro de tipo não possui restrições ou possui restrições que permitem valores nulos, a situação é um pouco mais complicada; isso significa que o tipo pode ser tanto nulável quanto não-nulável. O mais seguro a se fazer nessa situação é tratar o paramêtro tanto como nulável quanto não-nulável, gerando warnings quando um deles for violado.

Arrays

Arrays são especialmente desafiadores, já que não seria possível garantir que cada posição em um array não-nulável possuiria um valor.

Nós não conseguimos traçar de maneira adequada que todos os elementos de um array não-nulável foram inicializados. No entanto, poderíamos gerar um warning se nenhum elemento de um novo array é inicializado antes de ele ser lido ou passado para frente. Isso deve tratar o cenário mais comum sem causar muito incômodo.

Perguntas em aberto

O uso de default(T) deveria ser considerado um warning? Ou assume-se o retorno de T? ao invés de T?

Seria possível omitir ? em variáveis locais, com a nulidade sendo inferida baseada em seu uso?

Seria possível que os parâmetros automaticamente gerassem checagem para valores nulos?

Poderiam os valores nuláveis serem ajustados permitindo a escrita de x.method ao invés de x.value.method (isso seria aplicado quando fosse conhecido que x não é nulável)?

Mais informações

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT