serhio
serhio

Reputation: 28586

C# ? : operator

Could somebody explain me the following compiler issue

Error: Type of conditional expression cannot be determined because there is no implicit conversion between 'string' and 'int'

// WORKS
string text = string.Format(
    "the id is {0}", _Obj.Id.ToString());

// WORKS, without implicit conversion <<<
string text = string.Format(
    "the id is {0}", _Obj.Id);

// WORKS
string text = string.Format(
    "the id is {0}", (_Obj == null) ? "unknown" : _Obj.Id.ToString());

// NO WAY <<<
string text = string.Format(
    "the id is {0}", (_Obj == null) ? "unknown" : _Obj.Id);

in the last example, there is no implicit conversion, as well.

Upvotes: 4

Views: 803

Answers (8)

Mark Byers
Mark Byers

Reputation: 839114

The problem is nothing to do with your usage of string.Format. The problem is this expression:

(_Obj == null) ? "unknown" : _Obj.Id

The compiler cannot determine the type of this expression because there is no implicit conversion between int and string. You have already found the solution - calling ToString means that the expression returns a string in either case. Another way you could have fixed it (but slightly less efficient in this case because of boxing) is to tell the compiler explicitly how to perform the conversion. For example, you can use an explicit cast to object:

(_Obj == null) ? "unknown" : (object)_Obj.Id

Your second example works without an explicit cast because string.Format expects an object and there is an implicit conversion from int to object.

Upvotes: 9

Yogesh
Yogesh

Reputation: 14608

I think you need to read this from MSDN: Conditional Operator.

Specially this part:

The second and third operands of the ?: operator control the type of the conditional expression. Let X and Y be the types of the second and third operands. Then,

If X and Y are the same type, then this is the type of the conditional expression. Otherwise, if an implicit conversion (Section 6.1) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression. Otherwise, if an implicit conversion (Section 6.1) exists from Y to X, but not from X to Y, then X is the type of the conditional expression. Otherwise, no expression type can be determined, and a compile-time error occurs.

Upvotes: 1

Yves M.
Yves M.

Reputation: 3318

the problem is that

// WORKS, without implicit conversion 
string text = string.Format( 
    "the id is {0}", _Obj.Id); 

and

// NO WAY 
string text = string.Format( 
    "the id is {0}", (_Obj == null) ? "unknown" : _Obj.Id); 

are NOT the same!

Try to think the term

(_Obj == null) ? "unknown" : _Obj.Id);

as

function int Eval(object obj)
{
  if (obj == null)
  {
    return "unknown";
  }
  else
  {
    return "1";
  }
}

Which obviously is not working. So the whole thing has nothing to do with string.format.

Upvotes: 0

UpTheCreek
UpTheCreek

Reputation: 32391

The last one works because string.format will accept (string, object).

The first will not work because the ? : operator needs matching types.

Upvotes: 0

Nick Martyshchenko
Nick Martyshchenko

Reputation: 4249

"the id is {0}", (_Obj == null) ? "unknown" : _Obj.Id

compiler have to choose either pick string type or integer (guess) which is not can be exchanged vice versa by default (without implicit conversion)

string text = string.Format("the id is {0}", _Obj.Id)

string.Format takes object as arg, so no problem to convert Id (integer) to object.

Upvotes: 0

Gy&#246;rgy Andrasek
Gy&#246;rgy Andrasek

Reputation: 8277

What is the type this expression evaluates to?

(_Obj == null) ? "unknown" : _Obj.Id

Upvotes: 2

&#216;yvind Br&#229;then
&#216;yvind Br&#229;then

Reputation: 60734

in the first case (that does not work) if _Obj == null, you return a string, else your return an int. That of course causes a problem, since you in that case try to assign an int to string text.

Upvotes: -1

Related Questions