0

I can declare an Action and pass it a method on an instance object which modifies that object's internal state, then call the method and see that the private instance variables have changed. But if I create the Action, then null out the object it has a reference to a method on I don't get a null reference exception when I invoke the Action, but obviously I do if I try to access the object.

How can it be changing anything if there is nothing there to change?

A contrived example where I create a builder object which has a public void BuildWall method which just increments the number of walls it has built (a private integer variable). Why can I call buildWallAction after I have set builder to null or else how is the Action modifying the object if the object doesn't need to exist in order to call the action?

Thanks in advance :)

 class Program
{
    static void Main(string[] args)
    {
        Builder builder = new Builder("Jim");
        Console.WriteLine(builder.ToString());
        Action buildWallAction = builder.BuildWall;
        builder = null; //no more builder to change via BuildWall()
        //starts work

        buildWallAction();  //these calls modify _wallsBuilt on the builder object 
        buildWallAction();  //but if we set it to null we can still call them just fine

        Console.WriteLine(builder.GetBuildingStatus()); //we will only get an exception here if builder is null
        Console.ReadKey();
    }
}

public class Builder
{
    private string _name;
    private int _wallsBuilt;
    public Builder(string name)
    {
        _name = name;
        _wallsBuilt = 0;
    }

    public void BuildWall()
    {
        _wallsBuilt++;
    }

    public string GetBuildingStatus()
    {
        string msg = $"{_name} has built {_wallsBuilt} walls.";
        return msg;
    }
}
  • The action captures the `builder` variable as a closure - see http://stackoverflow.com/questions/9591476/are-lambda-expressions-in-c-sharp-closures – stuartd Dec 14 '16 at 11:24

1 Answers1

3

Your builder variable isn't the instance, it is a reference to the instance. So setting the variable to null, doesn't 'erase' the instance, you only get rid of the reference so you cannot access it anymore.

The buildWallAction variable is a reference to the method BuildWall of the instance. This is no way directly related to the builder variable. Setting the builder variable to null doesn't do anything to the buildWallAction variable.

Maarten
  • 22,527
  • 3
  • 47
  • 68