Be aware that there is one set of implicit conversions between integer types when the numbers are compile-time constants (literals), and another set of conversions when they are not constants.
Your interesting example is:
var value = test ? (UInt64)1 : 0;
which could also be written:
var value = test ? 1ul : 0;
where the ul
suffix means ulong
, i.e. System.UInt64
.
When literals (constants) are used there does exist an implicit conversion from int
(System.Int32
) to ulong
, but only when that int
constant is non-negative. It's really the same as:
const ulong a = 1ul;
const int b = 0;
var value = test ? a : b; // also works fine
It works, as I said, because of the implicit constant conversion from int
(since the compiler knows b
is not negative) to ulong
.
Now, take away the const
to get:
ulong a = 1ul;
int b = 0;
var value = test ? a : b; // compile-time error, no implicit conversion in either direction!
We see that with non-constants, no implicit conversion in either direction exists, so there's no best common type for a
and b
and this fails.