C#-装箱/拆箱/类型转换INT的问题。我不知道';我不明白
我很难理解这一点。考虑下面的例子:C#-装箱/拆箱/类型转换INT的问题。我不知道';我不明白,c#,c#-4.0,casting,boxing,unboxing,C#,C# 4.0,Casting,Boxing,Unboxing,我很难理解这一点。考虑下面的例子: protected void Page_Load(object sender, EventArgs e) { // No surprise that this works Int16 firstTest = Convert.ToInt16(0); int firstTest2 = (int)firstTest; // This also works object secondTest = 0; int seco
protected void Page_Load(object sender, EventArgs e)
{
// No surprise that this works
Int16 firstTest = Convert.ToInt16(0);
int firstTest2 = (int)firstTest;
// This also works
object secondTest = 0;
int secondTest2 = (int)secondTest;
// But this fails!
object thirdTest = Convert.ToInt16(0);
int thirdtest2 = (int)thirdTest; // It blows up on this line.
}
我在运行时遇到的特定错误是指定的强制转换无效。
如果我在Visual Studio中使用QuickWatch(int)thirdTest
,我会得到的值,无法将'thirdTest'取消装箱为'int'
这到底是怎么回事?取消装箱将检查中解释的确切类型 取消装箱是从类型对象到值的显式转换 类型或从接口类型转换为实现 接口。取消装箱操作包括:
- 检查对象实例以确保它是的装箱值 给定的值类型
- 将值从实例复制到值类型变量中
object thirdTest = Convert.ToInt16(0);
short thirdtest2 = (short)thirdTest;
所发生的事情正是它所说的 在第一种情况下,您有一个简短的、未装箱的,然后显式地将其类型转换为int。这是一个有效的转换,编译器知道如何进行,因此它可以工作 在第二种情况下,您有一个int,已装箱,正在重新分配给int。这是一个简单的整数解装箱,它也是有效的,因此可以工作 在第三种情况下,您有一个短的、已装箱的变量,您试图将其解装箱到一个非短的变量中。这不是有效的操作:不能一步完成。这也是一个常见的问题:例如,如果您使用的
SqlDataReader
包含SMALLINT
列,则无法执行以下操作:
int x = (int)rdr["SmallIntColumn"];
在您的第三个示例中,以下任一项都应适用:
object thirdTest = Convert.ToInt16(0);
int thirdTest2 = Convert.ToInt32(thirdTest);
int thirdTest3 = (int)(short)thirdTest;
Int16
是编写short
的奇特方式;这里没有装箱/拆箱,只有16位和32位整数之间的普通CLR转换
第二种情况是将框和解框设置为相同的类型,这是允许的:值类型int
被包装在对象中,然后被展开
第三种情况尝试取消装箱到不允许的其他类型(int
,而不是short
)。Int16实际上是一个short。因此,我认为可以将“Int16 firstTest=Convert.ToInt16(0);”使用“Int16 firstTest=0s;”或者使用正确的类型将其取消装箱,然后转换为所需的类型<代码>整数第三测试2=(整数)(短)第三测试代码>