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

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

鉴于这种

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发布了一个链接,这是我正在寻找的简洁的答案

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

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

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

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

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