Resharper陷阱“转换为'返回'声明”

时间:2009-03-09 17:17:24

标签: c# resharper ternary-operator

考虑以下例程:

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);
}

谁能发现陷阱?

1 个答案:

答案 0 :(得分:11)

好的,转到上一个答案。因为存在从Int64Double的隐式转换(但反之亦然),这将是表达式的结果类型。因此,当您希望得到一个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

取决于YZ的类型,我将其称为TYTZ。有几个选择:

  • TYTZ属于同一类型:结果是该类型
  • TYTZ进行隐式转换,但不是从TZ转换为TY:结果属于TZ类型,并且如果使用了第一个分支。
  • TZTY进行隐式转换,但不是从TY转换为TZ:结果属于TY类型,并且如果使用第二个分支。
  • 两个方向都有隐式转换:编译时错误
  • 无论如何都没有转换:编译时错误

这有帮助吗?