2010-03-15 12 views
8

Possibili duplicati:
Nullable types and the ternary operator. Why won’t this work?
Conditional operator assignment with nullable<value> types?Perché l'operatore condizionale non consente correttamente l'utilizzo di "null" per l'assegnazione ai tipi nullable?

Questo non verrà compilato, affermando "Tipo di un'espressione condizionale non può essere determinato, perché non v'è alcuna conversione implicita tra 'System.DateTime' e '' "

task.ActualEndDate = TextBoxActualEndDate.Text != "" ? DateTime.Parse(TextBoxActualEndDate.Text) : null; 

T le sue opere proprio bene

if (TextBoxActualEndDate.Text != "") 
    task.ActualEndDate = DateTime.Parse(TextBoxActualEndDate.Text); 
else 
    task.ActualEndDate = null; 
+2

Puoi sbarazzarti delle dipendenze dal tuo codice, quindi possiamo riprodurlo? Sostituisci 'task.ActualEndDate' con una variabile locale, ad esempio. –

+1

'int? q = vero? 3: null; ' – SLaks

risposta

8

Questo non funziona perché il compilatore non inserire una conversione implicita su entrambi i lati in una sola volta, e null richiede una conversione implicita per diventare un tipo nullable.

Invece, è possibile scrivere

task.ActualEndDate = TextBoxActualEndDate.Text != "" ? 
    DateTime.Parse(TextBoxActualEndDate.Text) : new DateTime?(); 

Ciò richiede una sola conversione implicita (DateTime-DateTime?).

In alternativa, si può lanciare qualsiasi lato sinistro:

task.ActualEndDate = TextBoxActualEndDate.Text != "" ? 
    (DateTime?)DateTime.Parse(TextBoxActualEndDate.Text) : null; 

Ciò richiede anche una sola conversione implicita.

+0

Dovresti davvero usare un DateTime.TryParse (TextBoxActualEndDate.Text, out someDateVar) lì. Non fidarti mai dell'input per darti una stringa parsabile. – Tomas

+2

Sì, ma non è il mio codice. – SLaks

+2

La convalida si verifica in un paio di posizioni prima di questa analisi e preferisco ora un'eccezione piuttosto che una quando cerco di inserire DateTime.Min nel database. –

4

L'operatore condizionale non osserva in che cosa viene restituito il valore. Guarda solo i valori a cui viene chiesto di scegliere tra: DateTime e null. Non è possibile identificarli come istanze dello stesso tipo (perché null non è un DateTime valido), quindi l'errore. Tu e io sappiamo che Nullable<DateTime> potrebbe fare il lavoro, ma l'operatore condizionale non è autorizzato a introdurre tipi "più grandi": è solo permesso di guardare i tipi delle due espressioni che sta scegliendo tra. (Grazie a Aaronaught nei commenti per chiarire questo punto e un bel esempio chiarificatore.)

Per aggirare questo, dare all'operatore un suggerimento lanciando il DateTime:

TextBoxActualEndDate.Text != "" ? (DateTime?)(DateTime.Parse(TextBoxActualEndDate.Text)) : null; 
            ^^^^^^^^^^^ 
+2

Principalmente corretto (+1): 'DateTime.Parse' restituisce un' DateTime' (non un 'Nullable '), che è un tipo di valore e non ha alcuna conversione in o da' null'. Il compilatore non ha la capacità di introdurre tipi "più grandi" nell'equazione quando tenta di risolvere l'espressione, può funzionare solo con i tipi che sono effettivamente lì. È lo stesso motivo per cui non puoi scrivere 'Stream s = expr? nuovo MemoryStream(): nuovo FileStream (...) '. – Aaronaught

+0

Aaronaught: ottima spiegazione - Lo spiegherò. – itowlson

0

La ragione è che nulla sia di tipo object in modo da avere un cast al tipo corretto, in questo modo:

task.ActualEndDate = TextBoxActualEndDate.Text != "" ? 
    DateTime.Parse(TextBoxActualEndDate.Text) : ((DateTime?) null); 
0

il modo più corretto (IMO) è quello di fare questo

task.ActualEndDate = TextBoxActualEndDate.Text != "" ? 
    (DateTime?)(DateTime.Parse(TextBoxActualEndDate.Text) : null); 

Uso spesso l'operatore nullo di compressione in questo modo.

0

Questo è l'errore, probabilmente, che si ottiene in questa situazione:

errore CS0173: Tipo di condizionale espressione non può essere determinato perché non c'è conversione implicita tra il '' e 'int')

Il compilatore sta spiegando che non sa come convertire null in un DateTime.


Fix:

è necessario castexplicitly la expression che può tornare null al tipo nullable. Questo funzionerà

((DateTime?) null); 
Problemi correlati