Você poderia explicar, por que Console.WriteLine escreve uma linha vazia ( Console.WriteLine(null)
me dá um erro de compilação) e por que não há NullReferenceException (nem a+=1
deveria levantá-la)?
int? a = null;
a++; // Why there is not NullReferenceException?
Console.WriteLine(a); // Empty line
++
,+=
e+
ter levantado variantes. Portanto, as instruçõesa++;
,a += 1;
ea = a + 1;
são permitidas. Cada produtonull
(sem exceção lançada)a
é inicialmentenull
.NullReferenceException
? masint?
não é umReference
, é apenas umint
que pode ternull
valorRespostas:
Você está observando os efeitos de um operador suspenso .
Da seção 7.3.7 da especificação C # 5:
Então, basicamente,
a++
neste caso, é uma expressão com um resultado denull
(as anint?
) e a variável é deixada intacta.Quando Você ligar
que está sendo encaixotado em
object
, o que o converte em uma referência nula, que é impressa como uma linha vazia.fonte
Console.WriteLine(a == null ? "null" : a)
?a
é do tipoint?
, eu diriaa ?? "null"
que não encontra um tipo comum para os dois operandos. Você precisa de uma dica queobject
seja do tipo comum. Portanto, converta qualquer operando para isso. Oa
será encaixotado. Por exemplo((object)a) ?? "null"
oua ?? (object)"null"
.A resposta de Jon está correta, mas gostaria de acrescentar algumas notas adicionais.
Existem 19 sobrecargas de
Console.WriteLine
e três delas são aplicáveis a anull
: a que tira astring
, a que tira achar[]
e a que tira aobject
. C # não pode determinar qual desses três você quer dizer, então ele dá um erro.Console.WriteLine((object)null)
seria legal porque agora está claro.a
é nuloint?
. A resolução de sobrecarga escolhe aobject
versão do método, portanto, oint?
é encaixotado em uma referência nula. Então, isso é basicamente o mesmo queConsole.WriteLine((object)null)
que escreve uma linha vazia.Onde está a referência nula com a qual você está preocupado?
a
é um nuloint?
que não é um tipo de referência para começar! Lembre-se de que os tipos de valor anulável são tipos de valor , não tipos de referência , portanto, não espere que eles tenham semântica de referência, a menos que sejam encaixotados em um tipo de referência. Não há boxe na adição.fonte
Esta declaração significa simplesmente,
null++
ou seja, nulo + 1.De acordo com este documento, um tipo anulável pode representar o intervalo correto de valores para seu tipo de valor subjacente, mais um valor nulo adicional. Um anulável, pronunciado "Anulável de Int32," pode receber qualquer valor de -2147483648 a 2147483647, ou pode ser atribuído o valor nulo
Aqui você está incrementando nulo, então também se tornará o valor nulo, não 0 ou qualquer outro inteiro.
quando você imprime um tipo anulável com valor nulo, ele imprime em branco em vez de erro porque você está imprimindo uma variável, ou seja, o valor de um local da memória. que pode ser nulo ou qualquer inteiro.
Mas quando você tenta imprimir null usando
Console.WriteLine(null)
, as null não é uma variável, então não se refere a nenhum local da memória. E, portanto, dá erro"NullReferenceException"
.Nesse caso, 2 ficará na memória em um local temporário e o ponteiro aponta para esse local de memória para imprimir.
fonte