我正在阅读微软的课堂培训材料。我读了以下内容
拆箱
拆箱与装箱相反。它是引用类型到引用类型的显式转换
值类型。拆箱检索对对象中包含的值类型的引用。
拆箱操作涉及检查对象实例以确保该对象
实例是给定值类型的装箱值。那么,实例的值是
复制到值类型变量中。
**
拆箱返回指向装箱对象内数据的指针,并且不创建数据的副本。
**
我不太明白我突出显示的那一行。它说,当拆箱装箱对象时,它不会创建副本,它只是返回一个指针。如果这是真的,那么值类型变量将被分配在堆中,对吗?
Ram
除了 Guffa 所说的之外,这里还有一些附加信息:
-
您引用的文字描述的“拆箱”操作描述了unbox
CIL指令。CIL 标准有这样的说法unbox
:
Unlike box
,这需要使
值类型的副本,用于
目的,unbox
is not需要复印
对象的值类型。
通常它只是简单地计算
值类型的地址是
已经存在于盒装内部
目的
-
您在 C# 中使用的拆箱转换是not编译为unbox
.它们被编译为另一条指令,称为unbox.any
:
[...] 这unbox.any
指令提取其中包含的值obj(类型O
)。 (相当于unbox
其次是ldobj
.)
在英语中,这意味着unbox.any
进行拆箱操作(unbox
) — 这推动了pointer到计算堆栈上 - 接下来是复制操作(ldobj
),它将指针转换为值类型中包含的实际值,并将其推送到计算堆栈上。
为了完整起见,这里是以下描述ldobj
:
The ldobj
指令复制一个值
到评估堆栈。 [...]src是一个非托管指针
(native int),或托管指针
(&)。 [...]
[理由:ldobj
指令可用于通过
值类型作为参数。结尾
理由]
据我所知,C# 编译器从不使用unbox
or ldobj
,它总是使用unbox.any
拆箱,以及ldind.*
取消引用引用(例如ref
/out
参数)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)