C# - 装箱/拆箱/类型转换整数问题。我不明白
我很难理解这一点。请考虑以下示例:
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.
}
我在运行时收到的具体错误是 Specifiedcast is not valid.
。如果我在 Visual Studio 中 QuickWatch (int)thirdTest
,我会得到以下值: 无法将“thirdTest”拆箱为“int”
。
这到底是怎么回事?
I'm having a hard time understanding this. Consider the following example:
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.
}
The specific error that I get at runtime is Specified cast is not valid.
If I QuickWatch (int)thirdTest
in Visual Studio, I get a value of Cannot unbox 'thirdTest' as a 'int'
.
What the heck is going on here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
拆箱检查确切的类型,如文档中所述。
正如您所看到的,第一步是检查对象实例是否与目标类型匹配。
还引用文档中的内容:
因此,要修复此错误,请在尝试拆箱之前确保类型匹配:
Unboxing checks the exact type as explained in the documentation.
As you can see the first step is to check that the object instance matches the target type.
Also quote from the documentation:
So to fix this error make sure that the type matches before attempting to unbox:
发生的事情正如它所说的那样。
在第一种情况下,您有一个简短的、未装箱的,然后将其显式转换为 int。这是编译器知道如何执行的有效转换,因此它可以工作。
在第二种情况下,您有一个装箱的 int,正在分配回 int。这是一个简单的整数拆箱,它也是有效的,所以它可以工作。
在第三种情况下,您有一个短的、装箱的,您试图将其拆箱为一个不是短的变量。这不是一项有效的操作:您无法一步完成此操作。这也不是一个罕见的问题:例如,如果您使用的是包含
SMALLINT
列的SqlDataReader
,则不能执行以下操作:以下任一操作应适用于你的第三个例子:
What's going on is exactly what it says.
In the first case, you have a short, unboxed, that you are then explicitly typecasting to an int. This is a valid conversion that the compiler knows how to do, so it works.
In the second case, you have an int, boxed, that are are assigning back to an int. This is a simple unboxing of an integer, which also valid, so it works.
In the third case, you have a short, boxed, that are you trying to unbox into a variable that is not a short. This isn't a valid operation: you can't do this in one step. This is not an uncommon problem, either: if you are using, for example, a
SqlDataReader
that contains aSMALLINT
column, you cannot do:Either of the following should work in your third example:
Int16
是一种编写short
的奇特方式;那里没有进行装箱/拆箱,只是 16 位和 32 位整数之间的普通 CLR 转换。第二种情况装箱和拆箱为相同的类型,这是允许的:值类型
int
被包装在object
中,然后被拆开。第三种情况尝试拆箱为不同类型(
int
而不是short
),这是不允许的。Int16
is a fancy way to writeshort
; there is no boxing/unboxing going on there, just the plain CLR conversion between 16-bit and 32-bit integers.The second case boxes and unboxes to the same type, which is allowed: value type
int
gets wrapped in anobject
, and then gets unwrapped.The third case tries to unbox to a different type (
int
instead ofshort
) which is not allowed.