Reference Type And Value Type in C#

Introduction

This article will give you a clear insight on what happens when a reference type is passed by value and what would happen when it is passed by reference.

Before diving into the deep sea of C#, I would like to touch the basics of reference and value types.

Reference Types: Always allocated from the managed heap.

Always represented in boxed form.

When we assign a value type to another value type, a field-by-field copy is made.

Value Types: Allocated on thread's stack

Have two form representations "boxed" and "unboxed"

When we copy a reference type to another reference type, only the memory address is copied.

Practical Time!!

Write down the following code and try guessing the output without running the program:

class Program
{
    static void Main(string[] args)
    {
        // Pass reference type by value
        ArrayList arrayList = new ArrayList() { 0, 1, 2, 3 };
         Console.WriteLine("Pass by Value");
 
        PassByValue(arrayList);

        // What should be the output of below line ??
        Console.WriteLine(arrayList[1]);
                arrayList = new ArrayList() { 0, 1, 2, 3 };

             Console.WriteLine("Pass by Reference");

        PassByReference(ref arrayList);

        // What should be the output of below line ??
        Console.WriteLine(arrayList[1]);

        Console.Read();
    }

    private static void PassByValue(ArrayList arrayList)
    {

        Console.WriteLine(arrayList[1]);
        // Now Change the first position value
        arrayList[1] = 90;
        arrayList = new ArrayList() { 101, 102, 103, 104 };

        Console.WriteLine(arrayList[1]);
    }

    private static void PassByReference(ref ArrayList arrayList)
    {

        Console.WriteLine(arrayList[1]);

        // Now Change the first position value
        arrayList[1] = 90;
             arrayList = new ArrayList() { 101, 102, 103, 104 };

        Console.WriteLine(arrayList[1]);
    }
}

Interpretation

First we'll take the case of passing value types by reference.

Let's have a look at the PassbyValue function:

The first line of code obviously would look out for value placed at second index in the arrayList and print out 1. After that, we change the value present at second index to 90. In the third line, since we had passed the reference type by value; it created a copy of original memory block pointing to the original memory location. But as soon we re-create the object, this loses the reference to the original memory location and acts as a different arrayList object then onwards. However, the changes done to the arrayList before the re-creation of object still persists. That's why, when we try to access the second index value, after the PassByValue function, we still get the output as 90.

Now, let's have a look at the Pass by Reference function:

Here too the first line of code output would be the same as reflected by the PassByValue function. The second would again change the value present at the second index to 90. In the third line, since we had passed the reference type by reference, it would just re-initialize its value to the new array (note that here the original memory location is getting new values overwritten here), thus the value for arrayList[1] inside the function would be 102 and after that the newly changed array would be referred everywhere, even outside the function.

Output

Reference

Conclusion

Passing reference types by Value creates a copy of the memory location and thus it is possible to change the value of the original reference type object inside the function (as soon we re-create that object). Passing reference types by ref doesn't create any copy of the object; it impacts the original reference object.


Similar Articles