通过ref-memory footprint在堆栈上传递'value type'

时间:2009-08-25 17:54:16

标签: c# .net memory

当我们通过引用传递一个已存储在堆栈中的值类型时,内存会发生什么?

必须在某处创建临时值/指针,以便在方法完成时更改origninal值。有人可以解释或指出我的答案 - 记忆中的很多东西,但似乎没有人回答这个问题。 TY

2 个答案:

答案 0 :(得分:4)

如果你有这样的方法:

static void Increment(ref int value)
{
   value = value + 1;
}

并将其称为:

int value = 5;
Increment(ref value);
然后会发生的是,不是将值5推入堆栈,而是将变量value的位置压入堆栈。即value的内容由Increment直接更改,而不是在方法完成后更改。

这里分别是方法和方法调用的IL:

.method private hidebysig static void Increment(int32& 'value') cil managed
{
    .maxstack 8
    L_0000: nop 
    L_0001: ldarg.0 
    L_0002: ldarg.0 
    L_0003: ldind.i4         // loads the value at the location of 'value'
    L_0004: ldc.i4.1 
    L_0005: add 
    L_0006: stind.i4         // stores the result at the location of 'value'
    L_0007: ret 
}

.method private hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 9
    .locals init ([0] int32 value) //   <-- only one variable declared
    L_0000: nop 
    L_0001: ldc.i4.5
    L_0002: stloc.0 
    L_0003: ldloca.s 'value'   // call Increment with the location of 'value'
    L_0005: call void Program::Increment(int32&)
    L_000a: ret 
}

答案 1 :(得分:0)

听起来你正在寻找关于拳击和拆箱的一些细节,这些术语用于描述将值类型视为参考类型。

有很多文章描述了这个过程,我会尝试找到一些不错的文章 - but here's one for starters