If you have a method like this:
static void Increment(ref int value)
{
value = value + 1;
}
and call it like this:
int value = 5;
Increment(ref value);
then what happens is that, instead of the value 5 being pushed on the stack, the location of the variable value
is pushed on the stack. I.e. the contents of value
are changed directly by Increment
and not after the method completes.
Here's the IL of the method and the method call respectively:
.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
}