2

これは私が遭遇した奇妙なものです。を返す関数がありますobject。特定のケースでは、オブジェクトが であることは確かですが、intこの関数を呼び出す別の関数にはfloat. これを機能させる唯一の方法は次のとおりです。

private object parser(string expr) {...}

private float parseFloat(string expr)
{
    ...
    object result = parser(expr);
    if (result is int)
        return (float)(int)result;
    else
        return (float)result;
}

この場合のパーサー関数の結果がint. (デバッガーで確認できます。) 次の行は単純にすることをお勧めします。

private float parseFloat(string expr)
{
    ...
    return (float)parser(expr);
}

(型チェックは事前に行われ、 orparseFloatに評価されない式で呼び出されるべきではありません。) この変数をダブルキャストする必要がある理由はありますか? からの戻り値がaである場合、最初に切り捨てられ、それを望まないため、すべての場合にダブルキャストしたくないことは明らかです。(そして、はい、 andをandなどに置き換えてみましたが、違いはありませんでした。)floatintparser floatintfloatintSingleInt32

私はこの質問を見ましたが、それは事前に型を知ることに依存しており、それが提供する唯一の解決策はこの二重キャストのトリックfloatです.結果を保持する変数。その余分なステップを回避する方法はありますか?

4

1 に答える 1

6

ボックスに入れられた値型をボックス化解除するときobjectは、正しいキャストを使用する必要があります。ある数値型から別の型への変換は、ボックス化解除後に行われる追加のキャストです。

ただし、あなたの場合、2 番目のキャストは実際には暗黙的であるため、次のように少し単純化できます。

if (result is int)
    return (int)result;
else
    return (float)result;

そもそもなぜ値型をボックス化するのですか? ボックス化されているタイプがわからない場合、ボックス化を解除するには、通常、is自分のやり方で確認する必要があります。

ただし、これらの組み込み数値型のような ( ) 型では、クラスIConvertibleも使用できることに注意してください。Convert

return Convert.ToSingle(result);

よりきれいに見えますが、速いとは思いません。おそらく同じ種類の型チェックを行うでしょう。

parser数値型のみを提供し、何らかの理由でこれらの値型をボックス化することを主張する場合は、それらをIConvertibleにボックス化することもできます。そのため、次のように戻り値の型を変更する必要があります。

private IConvertible parser(string expr) {...}

次に、コードは次のようになります。

IConvertible result = parser(expr);  // it's some number boxed in an IConvertible reference type
return result.ToSingle(null);  // instance method in IConvertible
于 2013-07-07T22:14:35.543 に答える