Questo fallisce con a There is no implicit conversion between 'null' and 'int'
long? myVar = Int64.Parse( myOtherVar) == 0 ? null : Int64.Parse( myOtherVar);
Tuttavia, questo ha esito positivo:
if( Int64.Parse( myOtherVar) == 0) myVar = null; else myVar = Int64.Parse( myOtherVar);
C’è un modo per far funzionare l’operatore ternario?
Il compilatore ignora il lato sinistro quando capisce il tipo del lato destro. Quindi quando cerca di dedurre il tipo di
Int64.Parse(myOtherVar) == 0 ? null : Int64.Parse(myOtherVar)
lo fa senza prestare attenzione al fatto che il lato sinistro è long?
. Per determinare il tipo di lato destro, lo nota
Int64.Parse(myOtherVar)
è un long
e ora prova a vedere se null
è o può essere convertito implicitamente in un long
. Dal momento che non può, ottieni il messaggio di errore che vedi.
Dal § 7.1 delle specifiche C #:
Un’espressione condizionale del modulo
b ? x : y
b ? x : y
….Il secondo e il terzo operando,
x
ey
, dell’operatore?:
Controllano il tipo di espressione condizionale.(1) Se
x
ha tipoX
ey
ha tipoY
alloraun. Se una conversione implicita (§6.1) esiste da
X
aY
, ma non daY
aX
, alloraY
è il tipo di espressione condizionale.b. Se esiste una conversione implicita (§6.1) da
Y
aX
, ma non daX
aY
,X
è il tipo di espressione condizionale.c. Altrimenti, non è ansible determinare alcun tipo di espressione e si verifica un errore in fase di compilazione.
(2) Se solo uno tra
x
ey
ha un tipo, ed entrambiy
, di sono convertibili in modo implicito per quel tipo, allora questo è il tipo di espressione condizionale.(3) Altrimenti, non è ansible determinare alcun tipo di espressione e si verifica un errore in fase di compilazione.
Nota che siamo in situazione (2) dove x
è null
e non ha un tipo y
è Int64.Parse(myOtherVar)
e ha tipo long
. Si noti che x
non è implicitamente convertibile nel tipo di y
. Quindi entrambi (1) e (2) falliscono sopra e risultiamo in (3) che risulta nell’errore di compilazione che ha ispirato la tua domanda. Si noti la conclusione implicita da quanto sopra che il lato sinistro non ha un ruolo nel determinare il tipo di lato destro.
Per rimediare a questa sostituzione
Int64.Parse(myOtherVar)
con
(long?)Int64.Parse(myOtherVar)
Ora, la ragione per cui
myVar = null;
va bene dove myVar
è dichiarato come long?
è perché il compilatore sa che esiste una conversione implicita da null
a long?
.
Infine, Int64.Parse
genererà se myOtherVar
non può essere analizzato a long
. Nota che stai anche eseguendo l’analisi due volte, il che non è necessario. Un modello migliore è
long value; if(Int64.TryParse(myOtherVar, out value)) { myVar = value == 0 ? null : (long?)value; } else { // handle case where myOtherVar couldn't be parsed }
L’utilizzo dell’operatore restituisce un Int64
, non un valore nullable
, a causa dell’ultima parte dell’operatore ternario. Potrebbe funzionare se invece lo fai:
long? myVar = Int64.Parse( myOtherVar) == 0 ? null : (long?)Int64.Parse( myOtherVar);
In modo che tu stia tornando un long?
invece, quindi il null
non ha bisogno di essere convertito in Int64
Inoltre, stai convertendo il valore due volte nel tuo codice, inutilmente (una volta per testare e una volta per ottenere il valore). Il tuo codice potrebbe essere migliore in questo modo:
long? tempVar = Int64.Parse(myOtherVar); long? myVar = tempVar==0? null : tempVar;
Sono sicuro che intendevi dire:
myVar = value == 0 ? null : (long?)value;
invece di
myVar = value == 0 ? null : value;
Mi è piaciuto l’uso della variabile ‘out’. Grazie.
Questo funzionerà:
long? myVar = (long?)myOtherVar == 0 ? null : (long?)myOtherVar;
..per coloro a cui piacciono le risposte brevi.
Il compilatore tenta di valutare le espressioni da sinistra a destra
long? myVar = Int64.Parse( myOtherVar) == 0 ? null : Int64.Parse( myOtherVar);
int64.parse
metodo int64.parse
restituisce un valore long
non un valore long
int64.parse
. quindi non c’è conversione tra null
e Int64.Parse( myOtherVar);
Quindi, prova questo
long? myVar = Int64.Parse(myOtherVar) == 0 ? (long?) null : Int64.Parse(myOtherVar);
O
long? myVar = Int64.Parse(myOtherVar) == 0 ? null : (long?) Int64.Parse(myOtherVar);