Are Reference Types In .Net Indeed Stored On The Heap ?
Tags: dotnet, memory, types
Published: 2020-03-02 04:03:34

---
title: Are Reference Types In .Net Indeed Stored On The Heap ?
published: true
description: understanding reference types, value types, memory allocation, and the ref keyword.
tags: dotnet,Memory,Types
---

The .Net type system is indeed an interesting topic, it is common place for interviewers to ask questions on this topic, and in most cases alot of engineers even experienced engineers misunderstand this topic.

Proper understanding on this topic, would infact help you build better efficient and performant applications.

So, back to the topic, in .Net the type system is majorly divided into two, *Reference Types* and *Value Types*.  If you ask alot of engineers what the difference is between the two, you might here, _reference types_ are allocated on the heap, while _value types_ are allocated on the stack.

But is this really true ?

Well, Yes and No... Let me explain.

In .Net everything is passed as a value, including reference types, they are passed as a value when passed as an argument to a method. What does this mean ?, let me explain with an example.

Say we have a method `Main` that declares two variables

```csharp
  public void Main()
  {
    var a = 5;
    Increment(a);
    var b = new Car("ford");
    Change(b);
  }

  public void Increment(int val)
  {
    val = 10;
  }

  public void Change(Car car)
  {
    car = new Car("mercedes");
  }

```

After the execution of the `Main` method what are the results ?, indeed because `a` is a value type, nothing new, the value dosen't change, despite it being changed in the called method. But something amazing happening here is the value of `b` despite it being a reference type the value still dosen't change.

So what does this mean ? yes indeed everything is copied by value in .Net, both reference types and value types.

But what is this value we are talking about ?. The answer lies inside what exactly a variable holds. In .Net when you declare a variable, the value of the variable is actually stored on the stack, for value types the value stored is actually the value it points to, for example, `var a = 5` the value stored on the stack is 5, for reference types, it gets interesting, the `new` keyword actually allocates memory on the managed heap, and returns the address, and this is what is stored on the stack.

That was why when we passed the reference type and changed it, nothing happened to the original variable, it is because the value on the stack(address to the heap) is what was indeed copied.

But if we changed the example a little , and replaced a value within the `car`, say we change the `Name` property in the `Change` method, you would notice that indeed the `Car` in main has changed. As what changes here is the value in the managed heap.

```csharp
  public void Main()
  {
    var a = 5;
    Increment(a);
    var b = new Car("ford");
    Change(b);
  }

  public void Increment(int val)
  {
    val = 10;
  }

  public void Change(Car car)
  {
    car.Name = "mercedes"; //this would change the value on the heap, so we are good.
  }

```

So in summary here, within a stack frame, all variables are allocated on the stack, wether reference types or value types. The difference here then is that for reference types, the value being saved on the stack, is the address to the type allocated on the heap. And every value passed to a method is copied by value, which basically is the value on the stack.


So, lets explore one other concept again. in .Net there is a keyword called `ref` , you might know it that when used to mark an argument in a method, it indicates that the argument is passed by reference and not value. So what does this mean from our findings above ? this means the value on the stack is exactly what is being passed by reference, independent of wether it is a value type or reference type. So lets see this in code.

```csharp
  public void Main()
  {
    var a = 5;
    Increment(ref a);
    var b = new Car("ford");
    var c = b;
    Change(ref b);
  }

  public void Increment(ref int val)
  {
    val = 10;
  }

  public void Change(ref Car car)
  {
    car = null;
  }

```

After the execution of the `main` method, sure enough, the value of `a` is changed to 10, because the ref keyword passes it by reference on the stack. While the value of `b` is changed to `null` because its value(memory address to the managed heap) on stack is changed. For variable `c`, it still points to the value on the managed heap, because even though it was assigned from `b` which is now null, they have different spaces on the stack.

In summary, from all these findings, you can use the `ref` keyword for value types when you want the called method to change the value (on the stack) and use it with reference types, when you want to replace the value (memory address) on the stack maybe to another new instance.

For engineers from a background of using pointers, you can see how the .Net type system, along with the ref keyword can properly allow you have a "pointers feel" without all the unnecessary problems that comes with pointers.