The compiler ignores the left-hand side when figuring out the type of the right-hand side. So when it tries to deduce the type of
Int64.Parse(myOtherVar) == 0 ? null : Int64.Parse(myOtherVar)
it does so without paying any attention to the fact the left-hand side is a long?
. To determine the type of the right-hand side it notes that
Int64.Parse(myOtherVar)
is a long
and now tries to see if null
is or can be implicitly converted to a long
. Since it can not, you get the error message that you see.
From §7.14 of the C# specification:
A conditional expression of the form b ? x : y
....
The second and third operands, x
and y
, of the ?:
operator control the type of the conditional expression.
(1) If x
has type X
and y
has type Y
then
a. If an implicit conversion (§6.1) exists from X
to Y
, but not from Y
to X
, then Y
is the type of the conditional expression.
b. If an implicit conversion (§6.1) exists from Y
to X
, but not from X
to Y
, then X
is the type of the conditional expression.
c. Otherwise, no expression type can be determined, and a compile-time error occurs.
(2) If only one of x
and y
has a type, and both x
and y
, of areimplicitly convertible to that type, then that is the type of the conditional expression.
(3) Otherwise, no expression type can be determined, and a compile-time error occurs.
Note that we are in situation (2) where x
is null
and does not have a type and y
is Int64.Parse(myOtherVar)
and has type long
. Note that x
is not implicitly convertible to the type of y
. Therefore both (1) and (2) fail above and we result in (3) which results in the compile-time error that inspired your question. Note the implicit conclusion from the above that the left-hand side does not play a role in determining the type of right-hand side.
To rectify this replace
Int64.Parse(myOtherVar)
with
(long?)Int64.Parse(myOtherVar)
Now, the reason why
myVar = null;
is okay where myVar
is declared as long?
is because the compiler knows there is an implicit conversion from null
to long?
.
Lastly, Int64.Parse
will throw if myOtherVar
can't be parsed to a long
. Note that you are also performing the parse twice, which is unnecessary. A better pattern is
long value;
if(Int64.TryParse(myOtherVar, out value)) {
myVar = value == 0 ? null : (long?)value;
}
else {
// handle case where myOtherVar couldn't be parsed
}