Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does a param that is passed by reference get updated?

Suppose I have a method like this:

public void MyCoolMethod(ref bool scannerEnabled)
{
    try
    {
        CallDangerousMethod();


    } 
    catch (FormatException exp)
    {
        try
        {
            //Disable scanner before validation.
            scannerEnabled = false;

            if (exp.Message == "FormatException")
            {
                MessageBox.Show(exp.Message);
            }
        }
        finally
        {
            //Enable scanner after validation.
            scannerEnabled = true;
        }
    }

And it is used like this:

    MyCoolMethod(ref MyScannerEnabledVar);

The scanner can fire at any time on a separate thread. The idea is to not let it if we are handling an exception.

The question I have is, does the call to MyCoolMethod update MyScannerEnabledVar when scannerEnabled is set or does it update it when the method exits?

Note: I did not write this code, I am just trying to refactor it safely.

like image 720
Vaccano Avatar asked Dec 22 '22 01:12

Vaccano


2 Answers

You can think of a ref as making an alias to a variable. It's not that the variable you pass is "passed by reference", it's that the parameter and the argument are the same variable, just with two different names. So updating one immediately updates the other, because there aren't actually two things here in the first place.

As SLaks notes, there are situations in VB that use copy-in-copy-out semantics. There are also, if I recall correctly, rare and obscure situations in which expression trees may be compiled into code that does copy-in-copy-out, but I do not recall the details.

If this code is intended to update the variable for reading on another thread, the fact that the variable is "immediately" updated is misleading. Remember, on multiple threads, reads and writes can be observed to move forwards and backwards in time with respect to each other if the reads and writes are not volatile. If the intention is to use the variable as a cross-thread communications mechanism them use an object actually designed for that purpose which is safe for that purpose. Use some sort of wait handle or mutex or whatever.

like image 70
Eric Lippert Avatar answered Feb 20 '23 00:02

Eric Lippert


It gets updated live, as it is assigned inside the method.

When you pass a parameter by reference, the runtime passes (an equivalent to) a pointer to the field or variable that you referenced. When the method assigns to the parameter, it assigns directly to whatever the reference is pointing to.

Note, by the way, that this is not always true in VB.

like image 38
SLaks Avatar answered Feb 20 '23 02:02

SLaks