Why does ?: cause a conversion error while if-else does not? [duplicate]
Solution 1:
Why can't I use
uint a = b == c ? 0 : 1;
?
The type of the expression b == c ? 0 : 1
is int
. As shown in this table, there is no implicit conversion from int
to uint
, so this is not allowed.
Why can I use
a = 0
?
Because there is special treatment of numeric types when the value is a constant expression.
From section 6.1.9 of the C# specification:
A constant expression of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type.
A constant expression of type long can be converted to type ulong, provided the value of the constant expression is not negative.
As indicated in the first bullet a = 0
and a = 1
are both allowed because 0
and 1
are constant expressions and are valid uint
values. Basically what this boils down to is that the compiler can easily determine at compile time that these conversions are valid, so it allows them.
Incidentally, if the b == c
part of your first example were changed to a constant expression (e.g. true
), then the whole conditional operator expression would be a constant expression and the code would compile.
Solution 2:
If b==c
were a constant expression then the whole conditional operator would be considered a constant expression and so, then, the rule allowing constant expressions of type int
to be converted to other int types would apply and it would compile.
Obviously, b==c
is not a constant expression and so the result of the conditional operator cannot be known until runtime and so the exemption that allows an implicit conversion of ints to uint (for constant expressions) does not apply.
In your if
/else
variant, both of the actual assignments are constant expressions.
Solution 3:
You should use literals to make your code work correctly like this:
uint a = b == c ? 0U : 1U;