2013-08-15 7 views
92

Perché non viene compilata?Il tipo di espressione condizionale non può essere determinato perché non esiste una conversione implicita tra "int" e <null>

int? number = true ? 5 : null; 

Tipo di espressione condizionale non può essere determinato perché non v'è alcuna conversione implicita tra 'int' e <nullo>

+0

Migliore spiegazione ed esempio ... [http://stackoverflow.com/questions/858080/nullable-types-and-the-ternary-operator-why-is-10-null-forbidden?answertab=active#tab ] (http://stackoverflow.com/questions/858080/nullable-types-and-the-ternary-operator-why-is-10-null-forbidden?answertab=active#tab-top) -top –

risposta

194

La specifica (§7.14) dice che per condizionale ex pression b ? x : y, ci sono tre possibilità, sia x e y entrambi hanno un tipo e determinate buone condizioni sono soddisfatte, uno solo dei x e y ha un tipo e determinate buone condizioni sono soddisfatte, o una compilazione -tempo si verifica errore. Qui, "alcune buone condizioni" significa che alcune conversioni sono possibili, che entreremo nei dettagli di seguito.

Ora, passiamo alla parte germano della specifica:

Se solo uno dei x e y ha un tipo, ed entrambi x e y sono implicitamente convertibile in quel tipo, allora questo è il tipo dell'espressione condizionale.

Il problema qui è che in

int? number = true ? 5 : null; 

solo uno dei risultati condizionali ha un tipo. Qui x è un int letterale, e y è null che fa non hanno un tipo e null non è implicitamente convertibile in una int . Pertanto, "alcune buone condizioni" non vengono soddisfatte e si verifica un errore in fase di compilazione.

Ci sono due modi per aggirare questo:

int? number = true ? (int?)5 : null; 

Qui siamo ancora nel caso in cui uno solo dei x e y ha un tipo. Si noti che nullancora non ha un tipo ma il compilatore non avrà alcun problema con questo, perché (int?)5 e null sono entrambi implicitamente convertibile in int? (§6.1.4 e §6.1.5).

L'altro modo è ovviamente:

int? number = true ? 5 : (int?)null; 

ma ora dobbiamo leggere un diverso clausola di nelle specifiche di capire perché questo è bene:

Se x è di tipo X e y ha tipo Y quindi

  • Se una conversione implicita (§6.1) esiste da X a Y, ma non da Y a X, quindi Y è il tipo di espressione condizionale.

  • Se una conversione implicita (§6.1) esiste fin Y a X, ma non da X a Y, quindi X è il tipo dell'espressione condizionale.

  • In caso contrario, non è possibile determinare alcun tipo di espressione e si verifica un errore in fase di compilazione.

Qui x è di tipo int e y è di tipo int?. Non c'è alcuna conversione implicita da int? a int, ma esiste una conversione implicita da int a int? in modo che il tipo dell'espressione sia int?.

: Nota inoltre che il tipo del lato sinistro viene ignorato nel determinare il tipo di espressione condizionale, una fonte comune di confusione qui.

+3

Buona citazione delle specifiche per illustrare perché questo accade - +1! – JerKimball

+1

Un'altra opzione è 'new int?()' Al posto di '(int?) Null'. – Guvante

+1

Questo è anche il caso se si ha un tipo di campo del database nullable, ad esempio un valore DateTime nullable e si prova a trasmettere dati a 'DateTime', quando è necessario' (DateTime?) ' –

38

null non ha alcun tipo identificabile - solo bisogno di un po sollecitazione per renderlo felice:

int? number = true ? 5 : (int?)null; 
+1

Oppure puoi fai 'int? numero = vero? 5: null as int?; ' –

+0

Bella risposta che inchioda il punto. Bella lettura correlata: http://ericlippert.com/2013/05/30/what-the-meaning-of-is-is/ –

+0

Il problema è * non * che 'null' non ha un tipo identificabile. Il problema è che non esiste alcuna conversione implicita da 'null' a' int'. Dettagli [qui] (http://stackoverflow.com/a/18260915/45914). – jason