I am trying to figure out why casts are required in the following examples:
bool test = new Random().NextDouble() >= 0.5;
short val = 5;
// Ex 1 - must cast 0 to short
short res = test ? 5 : 0; // fine
short res = test ? val : 0; // error
short res = test ? val : (short)0; // ugly
// Ex 2 - must cast either short or null to short?
short? nres = test ? val : null; // error
short? nres = test ? (short?)val : null; // ugly
short? nres = test ? val : (short?)null; // ugly
short? nres = test ? val : default(short?); // ugly
The first example just seems crazy to me. If short i = 0;
compiles, why can't the compiler implicitly treat the 0 (or any other valid short
value) as a short
in the above code?
The second example makes more sense to me. I understand that the compiler is unable to determine the type of the expression on the right side of the =
, but IMO it should take nullable types into account when doing so.
I'd like to understand if there is actual reasoning behind these compiler errors.
The expression
test ? val : 0
compiles just fine. You get an error in this line, because the type of this expression isint
and you're trying to assign it to ashort
variable. That requires an explicit cast. From C# language spec:Another question is why, for example, a literal
0
can be assigned to ashort
variable without a cast:And a result of ternary operator has to be cast:
The reason is that first assignment is evaluated at compile-time, because it consists only of constants. In such case, the implicit constant expression conversion rules apply:
The ternary operator can also be evaluated at compile time if all operands are constants:
In any other case, the stricter runtime conversion rules apply. All 3 statements below give compile errors:
For reference you can see Eric Lippert's comments.
The second example would require treating
Nullable<>
as a special case, like you already noticed.