Search code examples
c#pass-by-referencepass-by-value

Passing an object as a constructor parameter seems to be passing by reference instead of value


I'm having strange issue where I am creating a new object which contains a parameter for another object (paramObj) I use through my function. So, paramObj is used in an object constructor, but it ends up being altered after the constructor is called. Since C# is pass by value, I'm not sure why this is happening.

My code:

void MyFunction(List<string> filesets)
{
    foreach(Fileset fs in filesets)
    {
        //At this point, fs.allFiles.Count is 30. The MyNewObject class
        //takes a Fileset as a parameters and eventually clears the 
        //Fileset.allFiles List, making the count 0.
        MyNewObject tmpObj = new MyNewObject(fs, null, "default");

        //At this point, fs.allFiles.Count is 0, but I expect it to be 30

    }
}

The MyNewObject class simply clears the allFiles list contained within a Fileset class. Why is that showing up after the constructor if C# is pass by value?


Solution

  • You´re right in that everything in .NET is passed by value. Even references - and this is what fs actually is - are passed by value. Thus, when you pass fs around your method will have a copy of that reference. This reference however references the exact same object, making any change on that reference modifiying the backing object also.

    So in your constructor you have a second reference to the FileSet-instance referenced by fs.

    This more or less leads to the conclusion, that objects are effectivly passed by reference.

    There´s no simple way to circumvent this. It depends on why you even modify anything on that object within the constructor at all. You could try to copy the provided object referenced by fs within your constructor, e.g. by implementing IClonable within FileSet or by providing a copy-constructor within that class or whatever. However depending on what FileSet and it´s members are you will need some deep copy of the provided instance.

    For further reading on how to make a deep copy of an object look here: Deep cloning objects