C #? : оператор - PullRequest
       34

C #? : оператор

4 голосов
/ 15 ноября 2010

Может кто-нибудь объяснить мне следующую проблему компилятора

Ошибка: тип условного выражения не может быть определено, потому что есть нет неявного преобразования между 'string' и '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);

в последнем примере также не существует неявного преобразования.

Ответы [ 8 ]

10 голосов
/ 15 ноября 2010

Проблема не в том, что вы используете string.Format. Проблема заключается в следующем выражении:

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

Компилятор не может определить тип этого выражения, поскольку не существует неявного преобразования между int и string. Вы уже нашли решение - вызов ToString означает, что выражение возвращает string в любом случае. Другой способ, которым вы могли бы это исправить (но немного менее эффективный в этом случае из-за бокса), это явно сказать компилятору, как выполнить преобразование. Например, вы можете использовать явное приведение к object:

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

Ваш второй пример работает без явного приведения, поскольку string.Format ожидает object и существует неявное преобразование из int в object.

2 голосов
/ 15 ноября 2010

Какого типа это выражение оценивает?

(_Obj == null) ? "unknown" : _Obj.Id
1 голос
/ 15 ноября 2010

Я думаю, вам нужно прочитать это из MSDN: Условный оператор .

Специально эта часть:

Второй и третий операнды?:оператор управления типом условного выражения.Пусть X и Y будут типами второго и третьего операндов.Тогда

Если X и Y одного типа, то это тип условного выражения.В противном случае, если неявное преобразование (раздел 6.1) существует из X в Y, но не из Y в X, тогда Y является типом условного выражения.В противном случае, если неявное преобразование (раздел 6.1) существует из Y в X, но не из X в Y, тогда X является типом условного выражения.В противном случае тип выражения не может быть определен, и возникает ошибка времени компиляции.

0 голосов
/ 15 ноября 2010

проблема в том, что

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

и

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

НЕ одинаковы!

Попробуйте придумать термин

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

as

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

Что, очевидно, не работает.Так что все это не имеет ничего общего с string.format.

0 голосов
/ 15 ноября 2010

Последний работает , потому что string.format примет (string, object).

Первый из них не будет работать , поскольку оператору ? : требуется сопоставление типов.

0 голосов
/ 15 ноября 2010
"the id is {0}", (_Obj == null) ? "unknown" : _Obj.Id

компилятор должен выбрать либо тип string, либо integer (предположение), который нельзя заменить по умолчанию (без неявного преобразования)

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

string.Format принимает object в качестве аргумента, поэтому без проблем можно преобразовать Id (целое число) в объект.

0 голосов
/ 15 ноября 2010

в первом случае (это не работает), если _Obj == null, вы возвращаете string, иначе вы возвращаете int.Это, конечно, вызывает проблему, поскольку в этом случае вы пытаетесь назначить int на string text.

...