gpt4 book ai didi

.net - C# 值类型装箱。关于装箱包装器和值类型的大小和类型的问题

转载 作者:行者123 更新时间:2023-12-01 22:08:15 25 4
gpt4 key购买 nike

阅读后ValueTypes - RefTypes - EricLippert我有 3 个问题:

因为假设“int”派生自 System.ValueType,而 System.ValueType 又派生自 System.Object,

那么像“int”这样的值类型到底需要多少空间(看它最终是从 System.Object 派生的)?它只是 int 的大小还是用于区分它是值类型的额外 CLR 簿记字段。

“int”和“object”之间的大小差异?

当“int”用包装器装箱时。那么包装器是否只是一个对象类型(并且该对象进入堆)?这个包装对象和普通的 new object() 之间的区别?该包装器会产生多少大小/空间?

最佳答案

无论如何,int 都是 32 位,因为它是一个

Object 部分仅在您装箱后才发挥作用(例如在 C# 中将其转换为 object)。一旦发生这种情况,就会使用该对象拥有的所有内容创建一个新对象,并且该对象内部驻留您的 int。

这就是为什么与 Java 相比,C# 泛型如此神奇,因为您不会将值类型强制放入对象中,只是为了将它们放入泛型容器中,因此值类型实际上始终是值类型(或者直到程序员变得懒惰并开始到处乱扔object val=...)。

编辑:我可以理解这种困惑,因为他们对编译器的工作非常出色:

var s=12.GetType(); // if it looks like an object and walks like an object...

但它不是一个对象,直到GetType调用为止,此时该值被装箱到一个对象中,并且您可以调用它的虚拟方法。

这与从 Object 派生的 ValueType 相同。只是一些漂亮的语法糖,编译器会忽略并在你背后做一些奇怪的事情:)

edit2:这是显示装箱的反汇编代码:

.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 1
.locals init (
[0] class [mscorlib]System.Type s)
L_0000: nop
L_0001: ldc.i4.s 12
L_0003: box int32 // <---
L_0008: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
L_000d: stloc.0
L_000e: ldloc.0
L_000f: call void [mscorlib]System.Console::WriteLine(object)
L_0014: nop
L_0015: ret
}

关于.net - C# 值类型装箱。关于装箱包装器和值类型的大小和类型的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6206509/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com