Ловушка Resharper “Преобразовать в оператор 'return'”

StackOverflow https://stackoverflow.com/questions/627172

  •  06-07-2019
  •  | 
  •  

Вопрос

Учитывая следующую процедуру:

private static object ParseNumber(string token, FieldDefinition def)
{
  if (def.Fraction > 0)
    return Double.Parse(token);
  else
    return Int64.Parse(token);
}

Resharper предлагает мне возможность преобразовать его в оператор с помощью троичного оператора:

private static object ParseNumber(string token, FieldDefinition def)
{
  return def.Fraction > 0 ? Double.Parse(token) : Int64.Parse(token);
}

Кто может обнаружить ловушку?

Это было полезно?

Решение

Хорошо, перейдем к предыдущему ответу.Потому что существует неявное преобразование из Int64 Для Double (но не наоборот), это будет тип результата выражения.Итак, когда вы ожидаете получить упакованный Int64, вы на самом деле получаете упакованный Double (но со значением, которое изначально пришло из Int64.Parse).

На всякий случай, если это недостаточно ясно, давайте изменим все return операторы такие, что они просто возвращают переменную.Вот исходный код:

private static object ParseNumber(string token, FieldDefinition def)
{
  if (def.Fraction > 0)
    return Double.Parse(token);
  else
    return Int64.Parse(token);
}

Преобразуйте это соответствующим образом:

private static object ParseNumber(string token, FieldDefinition def)
{
  if (def.Fraction > 0)
  {
    double d = Double.Parse(token);
    object boxed = d; // Result is a boxed Double
    return boxed;
  }
  else
  {
    long l = Int64.Parse(token);
    object boxed = l; // Result is a boxed Int64
    return boxed;
  }
}

А теперь давайте проделаем то же самое с версией с условным оператором:

private static object ParseNumber(string token, FieldDefinition def)
{
  return def.Fraction > 0 ? Double.Parse(token) : Int64.Parse(token);
}

становится

private static object ParseNumber(string token, FieldDefinition def)
{
  // The Int64.Parse branch will implicitly convert to Double
  double d = def.Fraction > 0 ? Double.Parse(token) : Int64.Parse(token);
  object boxed = d; // *Always* a Double
  return boxed;
}

Редактировать:Как и было запрошено, немного больше информации.Тип условного выражения вида

X ? Y : Z

зависит от типов Y и Z, который я назову TY и TZ.Есть несколько вариантов:

  • TY и TZ являются одним и тем же типом:результатом является такой тип
  • Существует неявное преобразование из TY Для TZ но не от TZ Для TY:результат имеет вид TZ и преобразование используется, если используется первая ветвь.
  • Существует неявное преобразование из TZ Для TY но не от TY Для TZ:результат имеет вид TY и преобразование используется, если используется вторая ветвь.
  • Существует неявное преобразование в обоих направлениях:ошибка времени компиляции
  • В любом случае конверсий нет:ошибка времени компиляции

Помогает ли это?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top