Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Required casting using C# ternary conditional operator

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.

like image 383
andrew.cuthbert Avatar asked Oct 13 '15 17:10

andrew.cuthbert


People also ask

Why do we need casting in C#?

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.

What happens when casting in C?

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.

What are the two types of casting in C?

The two types of type casting in C are: Implicit Typecasting. Explicit Typecasting.

What does type casting C require?

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.


1 Answers

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.

like image 86
Jakub Lortz Avatar answered Oct 14 '22 00:10

Jakub Lortz