Thursday, December 3, 2015

Value vs Reference Types in C#

In today's blog post, I will be discussing the difference between value and reference types. There are certain misconceptions among people about the differences between the two.

Whenever there is a discussion on value vs reference types in C#, there are two user defined data types that come to mind: structs and classes. A struct is a value type and a class is a reference type. Let's understand their differences one by one.

Value Types

Suppose, we have a struct like this:

struct S
    private int x;
    private int y;

When we create an instance of this struct, the memory is allocated on the stack and only one space is created in the memory for the instance.

S instance = new S();

The space for instance gets allocated on the stack.
If we do,

S instance2 = instance;

A new instance called instance2 is created (on stack) and is completely independent of the instance variable's value.
So when we pass a value type as a method parameter, it comes as a complete separate copy. Any changes to it are not reflected back in the caller code.

Reference Types

Suppose, we have a class like this:

class C
    private int x;
    private int y;

When we create an instance of this class, 2 memory allocations happen: the variable is stored on the stack and object is stored on the heap.

C classInstance = new C();

So here classInstance variable is stored on stack and the actual object is stored on the heap. The classInstance variable simply refers to the object on the heap.

If we do,

C classInstance2 = classInstance;

classInstance2 is a new variable (created on stack) and it points to the same object (on heap) as referred by classInstance variable. So if we make any changes in the object using classInstance2 variable, the changes are reflected in classInstance variable's object too (because it's same). If I change the value of classInstance2.x, then classInstance.x is also changed. However, if I update the classInstance2 to refer to something else, for example if we set,

classInstance2= null;

It won't affect classInstance variable because we simply update the classInstance2 variable to point to a null reference. So when we pass objects like this to methods, the changes made to the object by the callee method are reflected back in the caller method. However, if we update the reference itself, that's not reflected back.

Ref Keyword

If in case, we want to update the reference too, we can use the ref keyword.

void Method1(ref C classInstance3)
    classInstance3 = null;

Method1(ref classInstance);

In this scenario, classInstance will be set to null by the callee method.


So we saw the differences between value and reference types in this article. We also saw that stack stores reference portion of reference-typed local variables and parameters and value typed local variables which are not part of a reference type. And heap stores content of reference type objects and anything inside a reference type object. So a generic statement like all value types are stored on stack might not be correct all the time as value types which are inside reference type objects are stored on heap.

For future updates to my weekly blog, please subscribe to my blog via the "Subscribe To Weekly Post" feature at the right and follow me on Twitter. Until then Happy Coding :)

No comments:

Post a Comment