Type of conditional expression cannot be determined because there is no implicit conversion between 'int' and <null>
Solution 1:
The spec (§7.14) says that for conditional expression b ? x : y
, there are three possibilities, either x
and y
both have a type and certain good conditions are met, only one of x
and y
has a type and certain good conditions are met, or a compile-time error occurs. Here, "certain good conditions" means certain conversions are possible, which we will get into the details of below.
Now, let's turn to the germane part of the spec:
If only one of
x
andy
has a type, and bothx
andy
are implicitly convertible to that type, then that is the type of the conditional expression.
The issue here is that in
int? number = true ? 5 : null;
only one of the conditional results has a type. Here x
is an int
literal, and y
is null
which does not have a type and null
is not implicitly convertible to an int
1. Therefore, "certain good conditions" aren't met, and a compile-time error occurs.
There are two ways around this:
int? number = true ? (int?)5 : null;
Here we are still in the case where only one of x
and y
has a type. Note that null
still does not have a type yet the compiler won't have any problem with this because (int?)5
and null
are both implicitly convertible to int?
(§6.1.4 and §6.1.5).
The other way is obviously:
int? number = true ? 5 : (int?)null;
but now we have to read a different clause in the spec to understand why this is okay:
If
x
has typeX
andy
has typeY
then
If an implicit conversion (§6.1) exists from
X
toY
, but not fromY
toX
, thenY
is the type of the conditional expression.If an implicit conversion (§6.1) exists from
Y
toX
, but not fromX
toY
, thenX
is the type of the conditional expression.Otherwise, no expression type can be determined, and a compile-time error occurs.
Here x
is of type int
and y
is of type int?
. There is no implicit conversion from int?
to int
, but there is an implicit conversion from int
to int?
so the type of the expression is int?
.
1: Note further that the type of the left-hand side is ignored in determining the type of the conditional expression, a common source of confusion here.
Solution 2:
null
does not have any identifiable type - it just needs a little prodding to make it happy:
int? number = true ? 5 : (int?)null;
Solution 3:
In C# 9
this is now allowed blog
Target typed ?? and ?
Sometimes conditional ?? and ?: expressions don’t have an obvious shared type between the branches. Such cases fail today, but C# 9.0 will allow them if there’s a target type that both branches convert to:
Person person = student ?? customer; // Shared base type
int? result = b ? 0 : null; // nullable value type
Or your example:
// Allowed in C# 9.
int? number = true ? 5 : null;