Perché l’incremento di Nullable non genera un’eccezione?

Potresti spiegare, perché Console.WriteLine scrive una riga vuota ( Console.WriteLine(null) mi dà errore di compilazione) e perché non c’è NullReferenceException (anche a+=1 non dovrebbe sollevarlo)?

 int? a = null; a++; // Why there is not NullReferenceException? Console.WriteLine(a); // Empty line 

Stai osservando gli effetti di un operatore sollevato .

Dalla sezione 7.3.7 della specifica C # 5:

Gli operatori Lifted consentono agli operatori predefiniti e definiti dall’utente di operare su tipi di valori non annullabili anche con forms nullable di questi tipi. Gli operatori Lifted sono costruiti da operatori predefiniti e definiti dall’utente che soddisfano determinati requisiti, come descritto di seguito:

  • Per gli operatori unari + ++ - -- ! ~ + ++ - -- ! ~ esiste una forma sollevata di un operatore se l’operando e i tipi di risultato sono entrambi tipi di valori non annullabili. La forma sollevata è costruita aggiungendo un singolo ? modificatore per l’operando e i tipi di risultato. L’operatore sollevato produce un valore nullo se l’operando è nullo. In caso contrario, l’operatore sollevato distriggers l’operando, applica l’operatore sottostante e avvolge il risultato.

Quindi, in sostanza, a++ in questo caso è un’espressione con un risultato null (come int? ) E la variabile non viene toccata.

Quando chiami

 Console.WriteLine(a); 

viene inserito in un object , che lo converte in un riferimento null, che viene stampato come una linea vuota.

La risposta di Jon è corretta, ma vorrei aggiungere alcune note aggiuntive.

Perché Console.WriteLine(null) fornisce un errore di compilazione?

Esistono 19 overload di Console.WriteLine e tre di essi sono applicabili a un null : quello che accetta una string , quella che prende un char[] e quello che accetta un object . C # non può determinare quale di questi tre intendi, quindi dà un errore. Console.WriteLine((object)null) sarebbe legale perché ora è chiaro.

perché Console.WriteLine(a) scrive una riga vuota?

a è un int? nullo int? . La risoluzione di sovraccarico sceglie la versione object del metodo, quindi l’ int? è inserito in un riferimento null. Quindi questo è praticamente lo stesso di Console.WriteLine((object)null) , che scrive una riga vuota.

Perché non c’è NullReferenceException sull’incremento?

Dov’è il riferimento null di cui sei preoccupato? a è un int? nullo int? che non è un tipo di riferimento per cominciare! Ricorda, i tipi di valori nullable sono tipi di valore , non tipi di riferimento , quindi non aspettarti che abbiano una semantica di riferimento a meno che non siano racchiusi in un tipo di riferimento. Non c’è boxe nell’aggiunta.

Stai incrementando null ???

 int? a = null; a++; 

Questa affermazione significa semplicemente null++ ie null + 1.

Come da questo documento, un tipo nullable può rappresentare l’intervallo di valori corretto per il suo tipo di valore sottostante, più un valore null aggiuntivo. A Nullable, pronunciato “Nullable of Int32”, può essere assegnato qualsiasi valore da -2147483648 a 2147483647, oppure può essere assegnato il valore nullo

Qui stai incrementando null, quindi diventerà un valore nullo non uguale a 0 o qualsiasi altro intero.

Perché stampa vuoto invece di errore ??

quando si stampa un tipo nullable con valore null, viene stampato vuoto invece di errore perché si stampa una variabile, ad es. il valore di una posizione di memoria. quale forse null o qualsiasi numero intero.

Ma quando provi a stampare null usando Console.WriteLine(null) , dato che null non è una variabile, quindi non si riferisce a nessuna locazione di memoria. E quindi dà errore "NullReferenceException" .

Quindi, come si può stampare qualsiasi numero intero usando Console.WriteLine(2); ??

In questo caso, 2 verrà memorizzato nella posizione temporanea e il puntatore rimanda a quella posizione di memoria da stampare.