Elliot Choules

Value and Reference Types

October 06, 2019

All types in C# are split into two categories, value and reference. There are some differences between these two groups and aren’t immediately obvious. But before we look into the difference between them, it’s probably a good idea to understand the Stack and the Heap.

When an application is run it is given a bunch of memory to work with. This memory is split into various sections but the majority of it is split into two areas, the Stack and Heap.

The Stack

The main purpose of the stack is to help keep track of the state of the application, including all of the local variables. Everytime the application enters a method a new frame (or container) is added onto the stack. Each frame consists of variables and parameters used for that method and also information about the current line of code that is running, which helps the stack keep track of the current state of execution.

Once a method has successfully executed, it is removed from the top of the stack and the next frame underneath becomes available. Only the frame at the top of the stack is accessible.

The Heap

The heap on the otherhand is used for the storage of data for the application. It makes it easy for the application to grab some space to allocate to information it needs to store.

Unlike the stack where the frames are stacked methodically, the blocks of data in the heap are scattered. Beacuse of the built-in garbage collector in C#, blocks of data can get moved around within the heap with the aim to help keep large blocks of space available for the application to use if necessary. Due to the data being moved around, we can’t simply use a memory address to grab it because that block of information could have moved to another memory address. Instead we can use a reference, which is continuously updated by the garbage collector so you will always to be able reach it.

Now that we have a better understanding of the stack and heap we can look at value and reference types.

Value Types: The contents of the variable lives where the variable lives on the stack. Examples of value types are int and double.

Reference Types: The contents of the variable lives in the heap. The variable doesn’t contain the data itself, just a reference to it in the heap. Examples of reference types are array and string.

When you assign a variable to be the value of another variable, it creates a copy of it. With value types it means you can change the value of one variable without affecting the other.

int a = 1;
int b = a;
b + 1; 

Console.WriteLine(a) // 1
Console.WriteLine(b) // 2

Reference types however, it creates a copy of the reference of the value. So if you change one variable it’ll affect the other because they’ll both be reference the same data block in the heap.

int[] a = new int[3] { 1, 2, 3 };
int[] b = a;
b[0] = 10;

Console.WriteLine(a[0]) // 10
Console.WriteLine(b[0]) // 10 

Elliot Choules

Developer and Umbraco Certified Professional.