从作为对象的int转换为float需要双重强制转换
本文关键字:转换 float 对象 int | 更新日期: 2023-09-27 18:21:29
这是我遇到的一个奇怪的。我有一个函数,它返回一个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
永远不应该用不会计算为float
或int
的表达式调用。)是否有必要对该变量进行双重强制转换?我显然不想在所有情况下都对其进行双重强制转换,因为如果parser
的返回是float
,它会首先将其截断为int
,我们不希望这样。(是的,我试着用Single
和Int32
等替换float
和int
。没有任何区别。)
我看到了这个问题,但这取决于提前知道类型,它提供的唯一解决方案是这种双铸技巧,在我的情况下,除非我先进行类型检查,否则会截断float
s,这也需要一个额外的局部变量来保存结果。有什么办法可以避免这一额外的步骤吗?
当您取消装箱已放入object
框中的值类型时,必须使用正确的强制转换。从一种数字类型到另一种类型的转换是取消装箱后的额外强制转换。
然而,在您的情况下,第二个强制转换实际上是隐式的,因此您可以将其简化为:
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