Reputation: 75
I came across the below lines of code recently.
public class Program
{
public static void Main(string[] args)
{
char x = 'X';
int i = 0;
Console.WriteLine (true ? x : 0);
Console.WriteLine(false ? i : x);
}
}
As per my knowledge, the above code should output the character 'X' in both the cases; However, I got 88 in the console when I execute the code; Can anyone help me understand why the output is ASCII code and not the character?
Upvotes: 1
Views: 781
Reputation: 74730
It's not the ternary operator per se, it's that chars can be implicitly converted to ints in c# so, faced with a scenario of the ternary expression having an int and a char and needing the "do if true" and "do if false" to be consistent the compiler will implicitly convert the char to an int. ints cannot be implicitly converted to chars so the compiler won't go that route
int result = bool ? someChar : someInt;
char result = bool ? (char)someInt : someChar;
These are both ok; one uses implicit conversion of someChar to int to achieve consistency (consistent int) for the ternary, the other uses an explicit cast of someInt to char to achieve consistent char
The firs one will result (print, in your case) an int, the second one will result in a char. You could also play with this:
int result = bool ? (char)someInt : someChar;
Explicit conversion of int to char, ternary results in char, implicit conversion to int when storing in result..
The ascii code for X is 88
Upvotes: 0
Reputation: 8815
A ternary operator has a type of its own. That's not always the same as the type of the two operands you pass into the statement. Instead, it's a type that both branches can convert to. In this case, char
has an implicit conversion to int
. That means the ternary statements type is int
. See the example below. The (true ? x : 0).GetType()
statement shows how the entire ternary statement has an int
type.
public class Program
{
public static void Main(string[] args)
{
char x = 'X';
int i = 0;
// Prints X fine
Console.WriteLine(x);
// Prints System.Int32
Console.WriteLine((true ? x : 0).GetType());
// Both print 88 - the int value of 'X'
Console.WriteLine(true ? x : 0);
Console.WriteLine(false ? i : x);
}
}
The "why" the compiler chooses int
and not char
is a bit more complicated. The C# spec defines that a char
is implicitly convertible to ushort
, int
, uint
, long
, float
, double
, and decimal
. It also says that any numeric type is explicitly convertible to char
. That's the key difference. Because the conversion from char
to int
is implicit (it doesn't require a cast), the compiler uses it for the ternary and ignores the potential conversion in the other direction. You can read more about the rules for determining the type of a ternary statement here.
Upvotes: 5
Reputation: 219117
Note that 'X'
is not a string
, it's a char
. The numeric value of which is 88
. This numeric value is important because the compiler needs to make sense of this operation:
true ? x : 0
Ultimately a ternary conditional operation has to produce a value. Intuitively, this value might be a char
or might be an int
. For the compilation of the code it can't be a maybe, it must always be one of them. Fortunately for the compiler, a char
can directly translate into an int
. In this case, 88
.
So the result of the operation is an int
, which is being printed to the console.
Upvotes: 0