简体   繁体   中英

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.

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 .

这个表达式的评估类型是什么?

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

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.

"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.

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

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

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 .

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM