Ловушка Resharper “Преобразовать в оператор 'return'”
-
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
и преобразование используется, если используется вторая ветвь. - Существует неявное преобразование в обоих направлениях:ошибка времени компиляции
- В любом случае конверсий нет:ошибка времени компиляции
Помогает ли это?