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.
When the variable of one data type is changed to another data type is known as the Type Casting. According to our needs, we can change the type of data. At the time of the compilation, C# is a statically-typed i.e., after the declaration of the variable, we cannot declare it again.
Type casting refers to changing an variable of one data type into another. The compiler will automatically change one type of data into another if it makes sense. For instance, if you assign an integer value to a floating-point variable, the compiler will convert the int to a float.
The two types of type casting in C are: Implicit Typecasting. Explicit Typecasting.
Type Casting is basically a process in C in which we change a variable belonging to one data type to another one. In type casting, the compiler automatically changes one data type to another one depending on what we want the program to do.
The expression test ? val : 0
compiles just fine. You get an error in this line, because the type of this expression is int
and you're trying to assign it to a short
variable. That requires an explicit cast. From C# language spec:
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.
Another question is why, for example, a literal 0
can be assigned to a short
variable without a cast:
short i = 0;
And a result of ternary operator has to be cast:
bool test = new Random().NextDouble() >= 0.5;
short val = 5;
short i = (short)(test ? val : 0);
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:
• A constant-expression (§7.19) 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.
The ternary operator can also be evaluated at compile time if all operands are constants:
short i = true ? 0 : int.MaxValue;
In any other case, the stricter runtime conversion rules apply. All 3 statements below give compile errors:
int intVal = 0;
short shortVal = 0;
bool boolVal = true;
short i = true ? 0 : intVal;
short j = true ? shortVal : 0;
short k = boolVal ? 0 : 0;
For reference you can see Eric Lippert's comments.
The second example would require treating Nullable<>
as a special case, like you already noticed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With