代码说明:
int i = 5;
object obj = i;
byte b = (byte)obj; // X
运行时,会在“X”行生成System.InvalidCastException(“指定的强制转换无效”)。做双重演员:
byte b = (byte)(int)obj;
我原本以为你应该能够将一个盒装的int(如果它的值在0..255范围内)转换成一个字节。任何人都可以对此有所了解吗?
(这是.net 2.0,如果重要的话)。
答案 0 :(得分:19)
您所看到的行为差异是identity and representation之间的差异。
取消装箱是身份演员,以及表示保留操作。然而,将int
投射到byte
是表示更改(因为可能会丢失精度)。
当您尝试将InvalidCastException
取消装箱为int
时,您会收到byte
,因为装箱值的标识不是{{1} },它是byte
。当你写int
时,你正在告诉运行时,我知道那里的内容 是byte b = (byte)obj
,但你真正想说的是什么是,我认为那里的内容可以转换到byte
。
为了制作后一种语句,首先必须声明对象的标识,即byte
。然后,只有这样,您才能将代码更改转换为int
。
请注意,即使目标类型为“较大” - 即byte
,这也适用。 目标类型不在源类型的继承树中的所有显式转换被视为表示更改。由于所有类型都来自Int64
,因此根据定义取消装箱无法更改表示形式。
答案 1 :(得分:5)
MSDN explicitly says取消装箱到其他类型会抛出InvalidCastException
。
我的理解是,取消装箱变量的类型实际上是underlying CIL assembly command的参数。它是unbox
操作码实际抛出InvalidCastException
。
如果是,则抛出InvalidCastException 对象未加框为valType。