?.
Identificando a complexidade invisível no código
Existem usos desnecessários do operador null-conditional (vulgo ?. ou ?[])
?[]
Exemplo:
if (pessoa?.Empresa?.Endereco?.Cidade?.Nome == "Campo Bom")
Pensamento comum:
Mas é só um caractere a mais! Não é melhor estar defendido de valores nulos?
Toda funcionalidade da linguagem tem um custo (cognitivo ou computacional).
Para embasar melhor a resposta, primeiro precisamos entender mais a fundo a implicação de usar o operador.
A?.B?.C?.Do();
Qual o tipo de retorno da seguinte expressão? (considerando que Invisivel é bool)
Invisivel
bool
var invisivel = funcionario?.Invisivel;
Existe problema no código abaixo?
if (funcionario?.Invisivel) { // ... }
E nesse?
await pessoa?.SalvarAsync();
São features das linguagens de programação que servem para facilitar cenários comuns, diminuindo a quantidade de código escrito. Geralmente são compiladas para outras funcionalidades mais rudimentares da linguagem. Alguns exemplos:
using
try ... finally
var
Usando o sharplab, podemos verificar como as features da linguagem são compiladas em diversos níveis: C#, IL, ASM. Também é possível ver a diferença de debug e release.
Podemos usar novamente o sharplab para verificar o impacto de ficar colocando ?. no código.
p?.Nome
(pessoa != null) ? pessoa.Nome : null
p?.Horario?.Nome
pessoa.Horario.Nome
pessoa?.Horario?.Nome
public string ConsistirDados(Pessoa pessoa) { if (string.IsNullOrWhiteSpace(pessoa?.Nome)) { return "Nome obrigatório"; } if (pessoa?.Empresa?.BloquearNovosCadastros == true) { return "A empresa da pessoa não permite novos cadastros"; } if (pessoa?.Tipo == TipoPessoa.Juridica && string.IsNullOrWhiteSpace(pessoa?.Cnpj)) { return "CNPJ obrigatório para pessoas jurídicas"; } // etc... return null; }
public string ConsistirDados(Pessoa pessoa) { if (pessoa == null) // Caso for um cenário de exceção, seria válido deixar estourar erro também { return "Pessoa não encontrada"; } if (string.IsNullOrWhiteSpace(pessoa.Nome)) { return "Nome obrigatório"; } if (pessoa.Empresa?.BloquearNovosCadastros == true) // É válido manter o `?.` aqui? { return "A empresa da pessoa não permite novos cadastros"; } if (pessoa.Tipo == TipoPessoa.Juridica && string.IsNullOrWhiteSpace(pessoa.Cnpj)) { return "CNPJ obrigatório para pessoas jurídicas"; } // etc... return null; }
null
await
As dicas comentadas e forma de pensar servem para muita coisa no desenvolvimento. Principalmente, o fato de entender como as coisas são implementadas para utilizar a melhor ferramenta para cada caso.
Sempre tenham curiosidade.