Reputation: 534
void Method(ref int refArgument)
{
refArgument = refArgument + 44;
}
int number = 1;
Method(ref number);
Console.WriteLine(number);
Under the hood, what is really happening?
It passes the memory address to the method/function and changes the value stored in that memory address?
OR
It creates a new memory address and stores the value in that newly created address and points the variable(number) to the new memory address?
Which is which?
My hunch is the first one since primitive data types in C# are struct and therefore they will always be pass by value
Upvotes: 1
Views: 604
Reputation: 3499
If we have a look at the IL code of your snippet:
IL_0000: nop
IL_0001: nop
IL_0002: ldc.i4.1
IL_0003: stloc.0 // number
// Loads the address of the local variable at a specific index onto the evaluation stack, short form. see: https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ldloca_s?view=netframework-4.7.2
IL_0004: ldloca.s 00 // number
IL_0006: call g__Method|0_0
IL_000B: nop
IL_000C: ldloc.0 // number
IL_000D: call System.Console.WriteLine
IL_0012: nop
IL_0013: ret
g__Method|0_0:
IL_0000: nop
// ldarg.0 called twice: 1. for ldind.i4 and 2. to store the result back to the memory location in stind.i4
IL_0001: ldarg.0
IL_0002: ldarg.0
// Loads a value of type int32 as an int32 onto the evaluation stack indirectly. see: https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ldind_i4?view=netframework-4.7.2
// --> It used the passed intptr
IL_0003: ldind.i4
IL_0004: ldc.i4.s 2C
IL_0006: add
// Stores a value of type int32 at a supplied address. see: https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_i4?view=netframework-4.7.2
IL_0007: stind.i4
IL_0008: ret
So it:
ldind.i4
loads the value from the supplied memory address and Pushes it onto the stackldc.i4.s 2C
loads 44 onto the stackadd
Does your addition with the two elements of the stackstind.i4
Stores the result of the addition back to the memory addressUpvotes: 6