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

(类型检查是事先完成的,并且parseFloat永远不应该使用不会计算为 afloat或的表达式来调用int。)是否有某些原因需要双重转换此变量?我显然不想在所有情况下都重复它,因为如果返回 fromparser a float,它会将它截断为intfirst 而我们不希望这样。(是的,我尝试用floatandint替换SingleandInt32等。没有任何区别。)

我看到了这个问题,但这取决于提前知道类型,它提供的唯一解决方案是这种双重转换技巧,在我的情况下,float除非我先进行类型检查,否则它会截断 s,这还需要额外的本地变量来保存结果。有什么办法可以避免这个额外的步骤?

4

1 回答 1

6

When you unbox a value type that has been put into an object box, you must use the correct cast. The conversion from one numeric type to another is an extra cast that comes after the unboxing.

In your case, however, the second cast is really implicit, so you could simplify a little bit to:

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

Why do you have boxed value types in the first place? If you don't know what type is boxed, to unbox you will normally have to check with is the way you do.

Note, however, that with (IConvertible) types like these built-in numeric types, you can also use the Convert class, so:

return Convert.ToSingle(result);

It looks more pretty, but I don't think it's faster. It will probably do the same kind of type checking.

If the parser gives only numeric types, and if for some reason you insist on boxing these value types, you might as well box them to IConvertible, so that involves changing the return type like this:

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

Then your code could go so:

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 回答