Search code examples
c#pointersreferencerefdereference

C# how dereferencing works behind the scenes


This code is from book named "Pro C# with .NET 6" and I wonder what happens behind the scenes while the reference to reference(ref Person p) is passed to the method. for example when we do p.personAge = 555; does dereferencing happen twice behind the scenes to first get to the variable which is being pointed to by p and then to get to value which the variable pointed by p contains? sorry if question is bit confusing but overall I want to know how dereferencing works in C#, in this case do we have 2 way dereferencing which happens automatically by the compiler?

static void SendAPersonByReference(ref Person p)
{
 // Change some data of "p".
 p.personAge = 555;
...
}

does dereferencing happens in this code too?

static void SendAPersonByReference(Person p)
{
 // Change some data of "p".
 p.personAge = 555;
...
}

Solution

  • Yes, there is a double-dereference; this is encoded in the IL; see here, with the key portion being:

    (by-reference)

        IL_0000: ldarg.0 # load the value of p, a ref-ref-Person (push 1)
        IL_0001: ldind.ref # dereference the ref-ref to a ref-Person (pop 1, push 1)
        IL_0002: ldc.i4 555 # load the constant integer 555 (push 1)
        IL_0007: stfld int32 Person::personAge # store to field (pop 2)
        IL_000c: ret
    

    vs (by value)

        IL_0000: ldarg.0 # load the value of p, a ref-Person (push 1)
        IL_0001: ldc.i4 555 # load the constant integer 555 (push 1)
        IL_0006: stfld int32 Person::personAge # store to field (pop 2)
        IL_000b: ret
    

    The ldind.ref is the extra dereference, from a ref Person (a reference to a reference) to a Person (a reference).