Dar*_*man 2 c# boxing casting object
这是我遇到的奇怪的一个.我有一个返回的函数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;
}
Run Code Online (Sandbox Code Playgroud)
没有那种类型检查,我根本无法让它工作,即使我知道在这种情况下解析器函数的结果是一个int.(你可以在调试器中看到它.)我更喜欢这条线:
private float parseFloat(string expr)
{
...
return (float)parser(expr);
}
Run Code Online (Sandbox Code Playgroud)
(类型检查是事先完成的,parseFloat不应该使用不会计算为float或的表达式调用int.)是否有必要对此变量进行双重转换?我显然不希望在所有情况下双投,因为如果返回的parser 是一个float,它会截断它int首先,我们不希望出现这种情况.(是的,我试图取代float,并int用Single和Int32等没有任何区别.)
我看到了这个问题,但这取决于提前知道类型,它提供的唯一解决方案是这个双重演绎技巧,在我的情况下会截断floats,除非我先进行类型检查,这还需要一个额外的本地保持结果的变量.有没有办法避免这一额外的步骤?
当您取消已放入object框中的值类型时,必须使用正确的强制转换.从一种数字类型到另一种数字类型的转换是拆箱后的额外转换.
但是,在你的情况下,第二个演员是非常隐含的,所以你可以简化一点:
if (result is int)
return (int)result;
else
return (float)result;
Run Code Online (Sandbox Code Playgroud)
为什么你首先有盒装价值类型?如果你不知道盒装什么类型,要取消装箱你通常需要检查is你的方式.
但是请注意,对于IConvertible像这些内置数值类型的()类型,您也可以使用Convert该类,因此:
return Convert.ToSingle(result);
Run Code Online (Sandbox Code Playgroud)
它看起来更漂亮,但我认为它不会更快.它可能会进行相同类型的检查.
如果parser只提供数字类型,并且如果由于某种原因你坚持装箱这些值类型,你也可以将它们装箱IConvertible,这样就包括改变返回类型,如下所示:
private IConvertible parser(string expr) {...}
Run Code Online (Sandbox Code Playgroud)
然后你的代码可以这样:
IConvertible result = parser(expr); // it's some number boxed in an IConvertible reference type
return result.ToSingle(null); // instance method in IConvertible
Run Code Online (Sandbox Code Playgroud)