6

次のルーチンが与えられます:

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

誰が罠を見つけることができますか?

4

1 に答える 1

13

さて、前の回答に変更します。Int64からへの暗黙的な変換があるためDouble(逆はありません)、それが式の結果の型になります。したがって、 boxed を取得することを期待すると、Int64実際には boxed が取得されます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

と のタイプに依存します。これをYandとZ呼びます。いくつかのオプションがあります:TYTZ

  • TYTZ同じ型です: 結果はその型です
  • from からtoへの暗黙的な変換がありますが、 from TYtoTZではありません。結果は型であり、最初の分岐が使用される場合は変換が使用されます。TZTYTZ
  • from からtoへの暗黙的な変換がありますが、 from TZtoTYではありません。結果は型であり、2 番目のブランチが使用される場合は変換が使用されます。TYTZTY
  • 両方向に暗黙の変換があります: コンパイル時エラー
  • どちらの方法でも変換はありません: コンパイル時エラー

それは役に立ちますか?

于 2009-03-09T17:26:12.037 に答える