1

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?

Harry
  • 75
  • 8

3 Answers3

5

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.

just.another.programmer
  • 8,579
  • 8
  • 51
  • 90
  • In that could you let me know why the int is not converted to char instead of converting char to int ? – Harry Feb 29 '20 at 17:49
  • 2
    @Harry: Because every `char` can be an `int`, but not every `int` can be a `char`. One data type is larger than the other. – David Feb 29 '20 at 17:50
  • @Harry - Two reasons. One - .NET prefers `int` as the default numeric type; when two things need to be converted to a common type, `int` is chosen most of the time. Second - a `char` can be converted to an `int` easily (in fact, it's really a `short` in disguise), but converting an `int` into a `char` doesn't make much sense. What char would `123456` be? – Vilx- Feb 29 '20 at 17:52
  • @Harry see my updated answer. Its' the difference between an _implicit_ and _explicit_ conversion. The ternary operator only works on _implicit_ conversions. – just.another.programmer Feb 29 '20 at 17:56
  • There are no implicit conversions from other types to `char`, as it stated [here](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/char#conversions) – Pavel Anikhouski Feb 29 '20 at 17:58
  • @PavelAnikhouski - I mentioned exactly that in the last paragraph of my answer. – just.another.programmer Feb 29 '20 at 18:00
0

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.

David
  • 208,112
  • 36
  • 198
  • 279
0

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

Caius Jard
  • 72,509
  • 5
  • 49
  • 80