简体   繁体   English

C#真正通过引用传递是通过引用传递吗?

[英]C# Pass by ref under the hood is it really pass by reference?

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 我的直觉是第一个,因为C#中的原始数据类型是struct,因此它们将始终按值传递

If we have a look at the IL code of your snippet: 如果我们看一下您的代码段的IL代码:

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://docs.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://docs.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://docs.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: 所以:

  1. ldind.i4 loads the value from the supplied memory address and Pushes it onto the stack ldind.i4从提供的内存地址中加载值并将其压入堆栈
  2. ldc.i4.s 2C loads 44 onto the stack ldc.i4.s 2C将44加载到堆栈上
  3. add Does your addition with the two elements of the stack add是否将堆栈的两个元素相加
  4. stind.i4 Stores the result of the addition back to the memory address stind.i4将相加的结果存储回内存地址

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM