Search code examples
c#operator-precedence

What is C# order of execution in function call with ref?


So I have just caught this bug in our code:

class A
{
    public int a;
}
var x = new A();
x.a = 1;
A qwe(ref A t) {
    t = new A();
    t.a = 2;
    return t;
}
void asd(A m, A n) {
    Console.WriteLine(m.a);
    Console.WriteLine(n.a);
}

asd(x, qwe(ref x));
asd(x, qwe(ref x));

Is the order of execution in function invocation specified regarding the order of parameters?

What is written here is:

1
2
2
2

Which means that the first parameter's reference is saved before the second parameter's function is invoked.

Is this defined behavior? I could not find specific information on the order of execution in C# lang spec.


Solution

  • C# requires that parameter expressions passed to methods be evaluated left-to-right.

    Even though the qwe finishes its work prior to invoking asd, C# has captured the reference to "old" A before invoking qwe in preparation for the call. That is why the first argument of the first invocation of asd gets the "old" A object, before it gets replaced with the new A object inside the qwe call.