Does passing Reference Types using ref save memory?

后端 未结 4 513

In C#, the parameters to a method can be either reference types or value types. When passing reference types, a copy of the reference is passed. This way, if inside a method

4条回答
  •  我在风中等你
    2021-01-04 20:26

    Claim

    No, it doesn't. If anything, it's slower because of the extra lookup.

    There's no reason to pass a reference type by reference unless you specifically intend to assign to it later.


    Proof

    Since some people seem to think that the compiler passes "the variable itself", take a look at the disassembly of this code:

    using System;
    
    static class Program
    {
        static void Test(ref object o) { GC.KeepAlive(o); }
    
        static void Main(string[] args)
        {
            object temp = args;
            Test(ref temp);
        }
    }
    

    which is (on x86, for simplicity):

    // Main():
    // Set up the stack
    00000000  push        ebp                    // Save the base pointer
    00000001  mov         ebp,esp                // Set up stack pointer
    00000003  sub         esp,8                  // Reserve space for local variables
    00000006  xor         eax,eax                // Zero out the EAX register
    
    // Copy the object reference to the local variable `temp` (I /think/)
    00000008  mov         dword ptr [ebp-4],eax  // Copy its content to memory (temp)
    0000000b  mov         dword ptr [ebp-8],ecx  // Copy ECX (where'd it come from??)
    0000000e  cmp         dword ptr ds:[00318D5Ch],0  // Compare this against zero
    00000015  je          0000001C               // Jump if it was null (?)
    00000017  call        6F910029               // (Calls some internal method, idk)
    
    // THIS is where our code finally starts running
    0000001c  mov         eax,dword ptr [ebp-8]  // Copy the reference to register
    0000001f  mov         dword ptr [ebp-4],eax  // ** COPY it AGAIN to memory
    00000022  lea         ecx,[ebp-4]            // ** Take the ADDRESS of the copy
    00000025  call        dword ptr ds:[00319734h] // Call the method
    
    // We're done with the call
    0000002b  nop                                // Do nothing (breakpoint helper)
    0000002c  mov         esp,ebp                // Restore stack
    0000002e  pop         ebp                    // Epilogue
    0000002f  ret                                // Return
    

    This was from an optimized compilation of the code. Clearly, there's an address of a variable being passed, and not "the variable itself".

提交回复
热议问题