Why ?: Causes a conversion error, but if-else doesn’t?

After making some changes to the code, I use the following line:

uint a = b == c ? 0 : 1; 

Visual Studio shows me this error:

It is not possible to implicitly convert the type 'int' to 'uint'. Explicit conversion exists (are you skipping listing?)

But if I use the code:

 uint a; if (b == c) a = 0; else a = 1; 

It works correctly without any errors or warnings. Why?

+75
c # type-conversion
Mar 09 '17 at 8:18
source share
3 answers

Why can't I use uint a = b == c ? 0 : 1; uint a = b == c ? 0 : 1; ?

Expression Type b == c ? 0 : 1 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 handling of numeric types when a 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 if 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 if the value of the constant expression is not negative.

As indicated in the first mark, a = 0 and a = 1 , both are allowed because 0 and 1 are constant expressions and are real uint values. It basically boils down to the fact that the compiler can easily determine at compile time that these transformations are valid, so it allows them.

By the way, if part of your first example b == c was changed to a constant expression (for example, true ), then the entire conditional expression of the operator will be a constant expression, and the code will compile.

+87
Mar 09 '17 at 8:27
source share
— -

If b==c were a constant expression, then the whole conditional operator would be considered a constant expression, and therefore, then a rule that allows you to convert constant expressions of type int to another int types will be applied and will be compiled.

Obviously, b==c not a constant expression, so the result of a conditional statement cannot be known before execution, therefore, an exception that allows implicit conversion of int to uint (for constant expressions) is not applied.

In your if / else variant, both actual assignments are constant expressions.

+26
Mar 09 '17 at 8:28
source share

You must use literals for your code to work correctly:

 uint a = b == c ? 0U : 1U; 
+10
Mar 09 '17 at 8:22
source share



All Articles