0

If i try to do this:

// As an example. char? c value is actually given by the user.
char? c = null;

WriteLine((c == null) ? "null" : c);

Where i am saying that if c equals null (c == null) then WriteLine() should output null to the console. Else it should output the value of c.

However i get this compiler error:

Type of conditional expression cannot be determined because there is no implicit conversion between 'string' and char?.

My workaround was to do this:

char? c = null;            
WriteLine((c == null) ? "null" : "{0}",c);

Or with C#6 and using String Interpolation

char? c = null;            
WriteLine((c == null) ? "null" : $"{c}");

Reading through similar compiler errors here in stackoverflow e.g.

Type of conditional expression cannot be determined because there is no implicit conversion between 'int' and <null>

or

Type of conditional expression cannot be determined because there is no implicit conversion between 'string' and 'System.DBNull'

Tells that the reason is the types must match. My question is why must the types match? Also since the error says there is no implicit conversion between string and char?, does that mean that there is an explicit conversion of string to char? (which obviously by logic can't be tha case here) or does it mean that there is from char? to string ?

Johnson
  • 401
  • 5
  • 14

1 Answers1

3

The compiler has to know what the type of the expression is. A character, and a pointer to character, are not the same thing.

It's obvious to you what you mean, but the compiler has to assign a type to every expression, so it will know which version of the WriteLine subroutine will be called. It cannot postpone that decision to run time - it has to decide it at compile time, so it has to know what type the ternary expression is.

Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
  • Thanks but can you explain a bit further? Cause the compiler (seems to me) knows that i am talking about a string and a char?. – Johnson Apr 13 '16 at 00:13
  • @GeorgeOscStephan, I'm confused which overload of `WriteLine` you expect the compiler to choose. – Kirk Woll Apr 13 '16 at 00:16
  • @KirkWoll What do you mean which overload? I want the compiler to choose the first expression if it is null and output it else it should choose the second expression and output it. – Johnson Apr 13 '16 at 00:20
  • 1
    @GeorgeOscStephan: Kirk is right. There are many `WriteLine` functions. There is `WriteLine(char)`, `WriteLine(string)`, `WriteLIne(int)`, etc. etc. The compiler has to be able to figure out which. This is not a dynamically-typed language. It is statically typed. It cannot postpone the decision. – Mike Dunlavey Apr 13 '16 at 00:23
  • @GeorgeOscStephan, right, but the first expression is of type `string` and the second expression is of type `char`. They are mutually incompatible. There exists a `WriteLine(string)` and a `WriteLine(char)` -- which of those do you expect the compiler to choose? – Kirk Woll Apr 13 '16 at 00:24
  • Thanks i understand the part of the compiler knowing before hand what type is it. But if i do this `string result = ((c == null) ? "null" : c);` Now there aren't any overloads so why does the compiler error again? Also UPvoted. – Johnson Apr 13 '16 at 00:28
  • @George: because now you are telling it what type you expect the result to be. Actually, if you take your original code and put the cast `(string)` in front of the ternary expression, I bet it will work. – Mike Dunlavey Apr 13 '16 at 00:30
  • Mike it didn't work still same error. You mean i do this right? `string result = (string)((c == null) ? "null" : c);` – Johnson Apr 13 '16 at 00:34
  • @George: OK, I take back my suggestion. Normally, data types have a hierarchy, so if you combine an `int` and a `double`, the `int` gets "coerced" to a `double`. But if you combine a `char` and a `string`, those two types are far enough apart that it will not coerce the `char` to a `string`. You can get away with this in more newbie-friendly languages like VB, but in more serious languages you're supposed to know the difference. – Mike Dunlavey Apr 13 '16 at 00:39
  • Understood it thanks. – Johnson Apr 13 '16 at 00:42
  • Its a mistake to talk about a string-literal as a "pointer-to-character" in C#. In C# (and .Net in general), `string` is a first-class object. They are only `char*`-types in C and C++. – abelenky Apr 13 '16 at 00:58