首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么将数组拆箱为不正确的类型不会在C#中抛出异常?

为什么将数组拆箱为不正确的类型不会在C#中抛出异常?
EN

Stack Overflow用户
提问于 2021-10-04 13:19:53
回答 1查看 115关注 0票数 4

值和数组的转换和拆箱有一种奇怪的不一致:

代码语言:javascript
复制
var us = new uint[] { 1, 2, 3 };

var i1 = (int)us[0];                 // direct value to value: works
var i2 = (int)(object)us[0];         // unboxing value to value: compiles, throws at runtime
var is1 = (int[])u;                  // direct array to array: does not compile
var is2 = (int[])(object)u;          // unboxing array to array: works!

is2.GetType().Name                   // UInt32[]

当禁止直接转换时,为什么允许数组拆箱?

EN

回答 1

Stack Overflow用户

发布于 2021-10-04 14:25:35

在禁止直接转换的情况下,为什么允许数组拆箱?

如果使用(int[])(object)us,您将进行两次转换,both of which are allowed by C#

  • from uint[] to object (您可以将任何引用类型转换为object)
  • from object to int[] (您可以从object转换为任何引用类型)

因此,(int[])(object)us进行了编译。

如果使用(int[])us,您将执行一次从int[]uint[]的转换,这是C#所不允许的。根据C#规范,只有当T[]U[]是引用类型时,才能从T转换为U,并且可以从T转换为Uintuint都不满足这两个条件,因此(int[])us无法编译。

在运行时,检查从uint[]int[]的转换,看它是成功还是失败。CLR确实允许这样做。请参阅CLR spec的第I.8.7.1节。

签名类型T与签名类型U兼容-当且仅当至少以下一项成立时。

..。

T是一个秩为r,元素类型为V的数组,U是一个秩为r,元素类型为W的数组,V是数组元素兼容的,与W。

..。

签名类型T是数组元素兼容的-当且仅当T具有基础类型V且U具有基础类型W并且:

  1. V与W兼容;或者
  2. V和W具有相同的简化类型。

intuint的“简化类型”都是int

这就是(int[])(object)us在运行时成功的原因。

还要注意,将us转换为object并不是“装箱”。这里的一切都是引用类型。您只是更改了引用的类型。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69436672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档