即。存储在堆栈中的值类型数据结构的名称是什么,它引用堆上的对象?
即。一个对象引用是System.What(如果有的话)?
我知道这不是pointer,不是吗?
我知道它“像”一个指针。
我知道它“归垃圾收集者所有”。
我超自然地相信当你实例化一个对象(即一个引用类型)时,IL会给CLR指令以在内存中分配“堆栈引用/堆值对”(例如
...
.locals init ([0] int32 i1,
[1] object o1,
[2] int64 l1)
IL_0000: nop
IL_0001: ldc.i4.4
IL_0002: stloc.0
IL_0003: newobj instance void [mscorlib]System.Object::.ctor()
IL_0008: stloc.1
IL_0009: ldloc.0
IL_000a: box [mscorlib]System.Int32
...
) ,并且在语言或IL级别上无法访问实际引用(复制/分配给新引用或操作引用对象除外),并且CLR / CLI创建和管理对象引用的分配,并且CLR注入OBJECTREF DWORD值进入堆栈(或类似)。
请让我直截了当,并为所有图书作者和谷歌搜索结束这一点。
谢谢!
答案 0 :(得分:4)
在堆栈上创建的值类型没有对堆上任何对象的引用 - 堆上没有相应的对象。这只会在列入值类型时创建 - 在这种情况下,这两者之间仍然没有任何关系。
这就是为什么当您更改盒装引用类型的值时,原始变量保持不变。无论什么时候装箱,都会创建一个新对象。
这是一个简单的方法:
private void TestBoxing()
{
int i = 52;
object io = i;
io = "something else";
}
这是生成的IL代码:
.method private hidebysig instance void TestBoxing() cil managed
{
// Code size 18 (0x12)
.maxstack 1
.locals init ([0] int32 i,
[1] object io)
IL_0000: nop
IL_0001: ldc.i4.s 52
IL_0003: stloc.0
IL_0004: ldloc.0
IL_0005: box [mscorlib]System.Int32
IL_000a: stloc.1
IL_000b: ldstr "something else"
IL_0010: stloc.1
IL_0011: ret
} // end of method Program::TestBoxing
正如您所看到的,这个.locals init ([0] int32 i, [1] object io)
只是启动局部变量,一个int和一个对象。
我在问具体是什么 堆栈上的引用类型 它指的是堆上的对象
它是普通对象引用,类似于所有对象引用,它引用内存中具有4字节类型指针和4字节同步块的点,然后休息与对象一样多的空间要求,在我们的例子中,int需要4个字节,所以12个字节。
嗯,我认为它没有名称,它是 CLR的内部指针(32位或64位,具体取决于运行时),它在CLR之外没有用,并且没有公开。如您所知,并且它由GC管理,因为在垃圾收集后对象在堆上移动后,值将会发生变化。
答案 1 :(得分:2)
它是一个指针,大小与本机字长相关(即x86上的32位指针,x64上的64位指针)。在我认为你的意思中,它没有CTS暴露的“类型”。