Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing reference type in C# [duplicate]

Tags:

c#

class Test
{
    static void Func(StringBuilder myString)
    {
        myString.Append ("test");
        myString = null;
    }
    static void Main()
    {
        StringBuilder s1 = new StringBuilder();
        Func(s1);
        Console.WriteLine (s1);
    }
}

The output is "Test", why isn't it null?

If s1 is passed by reference to Func(), then why does myString.Append("test") change it, but myString = null does not?

Thanks in advance.

like image 336
thomas Avatar asked Sep 13 '13 13:09

thomas


2 Answers

You're passing the reference to the object by value.

I.e. the address of the object is passed by value, but the address to the object and the object is the same. So when you call your method, the VM copies the reference; you're just changing a copy.

On myString.Append you're using the copied reference to get to the object (still only one object) which is then changed/invoked.

What you think you're doing is this:

class Test
{
    static void Func(ref StringBuilder myString)
    {
        myString.Append("test");
        myString = null;
    }
    static void Main(string[] args)
    {
        StringBuilder s1 = new StringBuilder();
        Func(ref s1);
        Console.WriteLine(s1);
    }
}

A longer explanation: http://javadude.com/articles/passbyvalue.htm

like image 150
Lasse Espeholt Avatar answered Sep 20 '22 15:09

Lasse Espeholt


if s1 is passed by reference to Func(), then why does myString.Append("test") does change it

Its not passed by references, instead its address value is passed to the function.

Suppose S1 is pointing to a memory location 0x48, This will be passed to Func, where Func parameter myString will start pointing to that location. Later when you Append a text to that location, it gets added. But later when you assign null to myString, it starts pointing to nothing, but the original location remains unchanged.

You should see: Parameter passing in C# by Jon Skeet

Consider the following diagrams. In Step 1, you create a new object of type StringBuilder and let S1 refers to that object.

enter image description here

In Step 2, after passing S1 to Func, now myString also points to the same object in memory.

enter image description here

Later when you Append, text through myString, it updates the original object, since myString is pointing to the memory location held by the object.

In Step 3, when you assign null to the myString it looses the address for StringBuilder object, but this doesn't change anything in the object or the pointer S1.

enter image description here

like image 34
Habib Avatar answered Sep 22 '22 15:09

Habib