Eu fiz algumas pesquisas sobre isso usando métodos diferentes para atribuir valores a um int nulo. Aqui está o que aconteceu quando eu fiz várias coisas. Deve esclarecer o que está acontecendo. Lembre-se: Nullable<something>
ou a abreviação something?
é uma estrutura para a qual o compilador parece estar fazendo muito trabalho para nos deixar usar com nulo como se fosse uma classe.
Como você verá abaixo, SomeNullable == null
e SomeNullable.HasValue
sempre retornará um esperado verdadeiro ou falso. Embora não demonstrado abaixo, também SomeNullable == 3
é válido (assumindo que SomeNullable é um int?
).
Enquanto SomeNullable.Value
isso, obtemos um erro de tempo de execução se atribuímos null
ao método, otimização do compilador e negócios de macaco.SomeNullable
. Este é, de fato, o único caso em que anuláveis podem nos causar um problema, graças a uma combinação de operadores sobrecarregados, sobrecarregados.object.Equals(obj)
Aqui está uma descrição de algum código que eu executei e qual saída ele produziu nos rótulos:
int? val = null;
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
Ok, vamos tentar o próximo método de inicialização:
int? val = new int?();
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
Tudo o mesmo de antes. Lembre-se de que a inicialização com int? val = new int?(null);
, com nulo passado para o construtor, teria produzido um erro de tempo COMPILE, pois VALUE do objeto anulável NÃO é anulável. É apenas o próprio objeto wrapper que pode ser igual a nulo.
Da mesma forma, receberíamos um erro de tempo de compilação em:
int? val = new int?();
val.Value = null;
para não mencionar que val.Value
é uma propriedade somente leitura de qualquer maneira, o que significa que não podemos nem usar algo como:
val.Value = 3;
mas, novamente, operadores de conversão implícita sobrecarregados polimórficos nos permitem:
val = 3;
Não há necessidade de se preocupar com o que você chama de polissom, desde que funcione corretamente? :)