Pergunta

Tenho procurado boas orientações sobre isso desde que o conceito foi introduzido no .net 2.0.

Por que eu iria querer usar tipos de dados não anuláveis ​​em c#?(Uma pergunta melhor é por que eu não escolheria tipos anuláveis ​​por padrão e só usaria tipos não anuláveis ​​quando isso explicitamente fizesse sentido.)

Existe um impacto "significativo" no desempenho na escolha de um tipo de dados anulável em vez de seu par não anulável?

Prefiro verificar meus valores em null em vez de Guid.empty, string.empty, DateTime.MinValue,<= 0, etc, e trabalhar com tipos anuláveis ​​em geral.E a única razão pela qual não escolho tipos anuláveis ​​com mais frequência é a sensação de coceira na parte de trás da minha cabeça que me faz sentir que é mais do que compatibilidade com versões anteriores que força esse extra '?' personagem para permitir explicitamente um valor nulo.

Existe alguém por aí que sempre (quase sempre) escolhe tipos anuláveis ​​em vez de tipos não anuláveis?

Obrigado pelo seu tempo,

Foi útil?

Solução

A razão pela qual você nem sempre deve usar tipos anuláveis ​​é que às vezes você pode garantir que um valor vai ser inicializado.E você deve tentar projetar seu código para que isso aconteça com a maior frequência possível.Se não houver como um valor não ser inicializado, não há razão para que null seja um valor válido para ele.Como um exemplo muito simples, considere isto:

List<int> list = new List<int>()
int c = list.Count;

Isso é sempre válido.Não há nenhuma maneira possível de c pode ser não inicializado.Se fosse transformado em int?, você estaria efetivamente informando aos leitores do código "este valor pode ser nulo.Certifique-se de verificar antes de usá-lo".Mas sabemos que isso nunca poderá acontecer, então por que não expor essa garantia no código?

Você está absolutamente certo nos casos em que um valor é opcional.Se tivermos uma função que pode ou não retornar uma string, retorne nulo.Não retorne string.Empty().Não retorne "valores mágicos".

Mas nem todos os valores são opcionais.E tornar tudo opcional torna o restante do seu código muito mais complicado (adiciona outro caminho de código que precisa ser manipulado).

Se você pode garantir especificamente que esse valor sempre será válido, então por que descartar essa informação?Isso é o que você faz ao torná-lo um tipo anulável.Agora o valor pode ou não existir, e qualquer pessoa que use o valor terá que lidar com ambos os casos.Mas você sabe que, em primeiro lugar, apenas um desses casos é possível.Portanto, faça um favor aos usuários do seu código e reflita esse fato no seu código.Qualquer usuário do seu código pode então confiar que o valor é válido e só precisa lidar com um único caso em vez de dois.

Outras dicas

Porque é inconveniente sempre ter que verificar se o tipo anulável é null.

Obviamente, há situações em que um valor é genuinamente opcional e, nesses casos, faz sentido usar um tipo anulável em vez de números mágicos, etc., mas sempre que possível, eu tentaria evitá-los.

// nice and simple, this will always work
int a = myInt;

// compiler won't let you do this
int b = myNullableInt;

// compiler allows these, but causes runtime error if myNullableInt is null
int c = (int)myNullableInt;
int d = myNullableInt.Value;    

// instead you need to do something like these, cumbersome and less readable
int e = myNullableInt ?? defaultValue;
int f = myNullableInt.HasValue ? myNullableInt : GetValueFromSomewhere();

Acho que os designers de linguagem acham que 'tipos de referência anuláveis ​​por padrão' foi um erro e que não anulável é o único padrão sensato, e você deve optar pela nulidade.(É assim que acontece em muitas linguagens funcionais modernas.) "null" geralmente é um monte de problemas.

Você parece ter 2 perguntas diferentes...

Por que eu iria querer usar tipos de dados não anuláveis ​​em C#?

Simples, porque o compilador garante que os dados do tipo de valor nos quais você está confiando realmente tenham um valor!

Por que eu não escolheria tipos anuláveis ​​por padrão e só usaria tipos não anuláveis ​​quando isso explicitamente fizesse sentido?

Como Joel já mencionou, um tipo só pode ser nulo se for um tipo de referência.Os tipos de valor são garantidos pelo compilador para terem um valor.Se o seu programa depende de uma variável para ter um valor, então este é o comportamento que você desejará ao não escolher um tipo anulável.

É claro que, quando seus dados vêm de qualquer lugar que não seja o seu programa, todas as apostas estão canceladas.O melhor exemplo vem de um banco de dados.Os campos do banco de dados podem ser null, então você gostaria que sua variável de programa imitasse esse valor - e não apenas criasse um valor "mágico" (ou seja,-1, 0 ou qualquer outro) que "representa" null.Você faz isso com tipos anuláveis.

Embora os valores nulos possam ser convenientes para uso como valores "ainda não inicializados" ou "não especificados", eles tornam o código mais complexo, principalmente porque você está sobrecarregando o significado de null bem como a variável (número ou nulo vs.apenas um número).

Os valores NULL são preferidos por muitos designers de banco de dados e programadores de banco de dados SQL, mas com uma pequena mudança no pensamento sobre o problema, você pode acabar com os valores nulos e realmente ter um código mais simples e confiável (por exemplo, sem se preocupar com NullReferenceExceptione).

Na verdade, há uma grande demanda por um "T!" Operador que torna algum tipo de referência não nulo, semelhante ao "T?" Torna os tipos de valor nulos, e Anders Hejlsberg, o inventor de C#, desejou incluir a capacidade.

Veja também a pergunta, Por que “nulo” está presente em C# e Java?

Costumo usar tipos Nullable sempre que fizerem sentido - não vou me importar com o desempenho até que seja um problema, então consertarei as poucas áreas onde ele está e pronto.

No entanto, também acho que, em geral, a maioria dos meus valores acaba sendo não anulável.Na verdade, muitas vezes eu gostaria de usar um NotNullable com tipos de referência para descobrir um problema nulo quando obtenho o nulo, e não mais tarde, quando tento usá-lo.

A única vez que um tipo anulável deve ser usado é no caso de um determinado campo em uma tabela do banco de dados exigir absolutamente que um nulo seja enviado ou recebido pelo aplicativo em algum momento.Mesmo nesse caso, deve-se sempre tentar encontrar uma maneira de contornar o uso do tipo anulável.Bool nem sempre é seu melhor amigo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top