passing object references by value in C#

var test = new TestClass();

SomeMethod(test);
Console.WriteLine(test);

SomeMethod2(test);
Console.WriteLine(test);

Console.ReadKey();

void SomeMethod(TestClass a)
{
    a = null; 
    
}

void SomeMethod2(TestClass a)
{
    a.intThing = 1;

}

public class TestClass
{
    public int intThing =0;

    public override string ToString()
    {
        return $"{intThing}";
    }
}

A bit confused on the output of this here – SomeMethod which passes in a and sets a=null does not modify the initial test object whatsoever, however setting the intThing field to 1 in SomeMethod2 modifies the initial test object. Whats going on with this? Why can’t I set the test object to null in SomeMethod by passing it in? I know that the reference to test in memory is being passed by value into the methods – I’m just confused why setting a equal to null doesn’t act on the object.

>Solution :

Because you are passing reference to the object by value, a is just a local variable storing the reference to the object in memory and setting a to null will not affect other variables storing that reference. a.intThing = 1; in the second method on the other hand modifies the object by reference (i.e. both test and a point to the same place in memory and you change it).

You can use ref keyword to make the first snippet work as desired:

When used in a method’s parameter list, the ref keyword indicates that an argument is passed by reference, not by value. The ref keyword makes the formal parameter an alias for the argument, which must be a variable. In other words, any operation on the parameter is made on the argument.

SomeMethod(ref test);

void SomeMethod(ref TestClass a)
{
    a = null;     
}

This will result in test set to null.

Read also:

Leave a Reply