拳击困惑。将-1转换为Int64会引发InvalidCastException

时间:2010-10-13 18:13:46

标签: c# .net language-design language-features

好的,我必须忽略一些非常简单的东西,但我迷失了。

鉴于此

object val = -1;
var foo = (Int32)(val);
var bar = (Int64)(val);

强制转换为Int64并发生InvalidCastException。

我认识到这与拳击的一些陌生感有关,但我不明白推理。

根据我的理解,val在第一行被装箱为Int32。

然后当我尝试强制转换为Int32以外的东西时抛出InvalidCastException。我想这意味着当我实际上是Int32时,我试图将其作为Int64解包?

看起来仍然很奇怪。无法播放取消装箱值,然后尝试执行演员表?

类似的东西(显然这是可怕的过度简化,也许盒装类型未知,所以这是不可能的?):

object val = -1;
Int32 unboxed = (Int32)(val);
var bar = (Int64)(unboxed);

有人(读:Eric Lippert)向我介绍了这背后的原因。

更新:来自Eric的博客,Reed发布了一个链接,这是我正在寻找的简洁答案

“......这将产生大量的代码,而且速度非常慢。代码当然是如此之大,以至于您希望将其放入自己的方法中并生成一个调用它。而不是默认情况下执行此操作,并始终生成缓慢,大而脆弱的代码,相反,我们认为取消装箱只能取消装箱到确切类型。如果要调用所有goo的慢速方法,它是可用的 - 你总是可以调用Convert.ToInt32,它会在运行时为你做所有的分析。我们给你选择“快速和精确”或“慢和松弛”,以及合理的默认值是前者。如果你想要后者,那么调用方法....“

1 个答案:

答案 0 :(得分:15)

这是因为您无法在单个操作中取消装箱并执行转换。您必须将Int32值拆分为Int32,然后再转换其类型。

因此,这需要将对象取消装箱,然后转换为Int64:

object val = -1;
int foo = (Int32)val;
Int64 bar = (Int64)(Int32)val;

Eric Lippert在他的博客文章Representation and Identity中详细介绍了这一点。