c# - 被拳击迷惑。将 -1 转换为 Int64 会抛出 InvalidCastException

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

好吧,我一定是忽略了一些非常简单的东西,但我迷路了。

鉴于此

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

转换为 Int64 抛出 InvalidCastException。

我知道这与拳击的一些奇怪之处有关,但我不明白其中的原因。

据我所知,val 在第一行被装箱为 Int32。

然后,当我尝试转换为 Int32 以外的其他内容时,将抛出 InvalidCastException。我想这意味着当它实际上是 Int32 时,我正试图将 val 拆箱为 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 的博文中对此进行了详细介绍.

关于c# - 被拳击迷惑。将 -1 转换为 Int64 会抛出 InvalidCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3926654/

相关文章:

c# - 如何有效地只读取文本文件的最后一行

c# - 使用 C# 读取组策略设置

c# - Ninject拦截动态代理问题

c# - 使用反射从资源中获取值(value)

c# - DataGridView 中的复选框未触发 CellValueChanged 事件

.net - 无法使用 Visual Basic 将具有 12 位小数的 double /十进制值转换为字符串

c++ - 是否存在阻止内置函数拥有静态成员的技术限制?

.net - Oracle ODP.Net 与 Entity Framework 6 - 找不到 Entity Framework 数据库兼容提供程序

c# - System.ValueType 是否继承自 System.Object?

garbage-collection - 如何在没有 gc 的情况下实现闭包?