Value Type and Reference Type in C#

In this post, we will try to cover the topic of value type and reference type in C# programming language.

Pictorial representation of Data types in C#

Data types in C# are illustrated in the diagram below.

Value type and reference type in C#
Data types in C#

The two main categories of C# types are as follows.

    • Value Type
    • Reference Type

Value Type In C#

Value types in C# are generally saved in the stack memory, while reference types are kept in the managed heap. A value type is a type that inherits from System.ValueType and stores data in its own memory allocation.

To put it another way, each variable, object, and value type has its own copy of the data.
In C#, a value type does not carry a reference; instead, it stores the actual value in its own stack memory location.
This means that these data types’ variables directly contain values.

In C#, there are two kinds of value types: 

    • Built-in value types in C#
    • User-defined value type in C#

int, long, float, double, byte, decimal, char, bool, short are a few examples of Built-in value types.

struct and enum are examples of user-defined value types.

Example of ‘value types in C#’

Consider the code snippet below as an example of a value type in C#.

using System;
class Program
{
    static void Main()
    { 
        // Here, integer x and y variables are value types
        int x = 100;
        int y  =  x;
        // increment y by 1
            y++; 
      
        Console.WriteLine($"x = {x} y = {y}");
        Console.ReadLine();
    }
    // Output: x = 100 y = 101
}

Let’s execute the above program and see the result.

Value type output
The output of the above program.

Both x and y will be present on the stack memory, but they are separate entities.

Reference type in C#

All the reference types in C# are derived from System.Object class.
Instead of storing its value directly, a reference type carries a pointer to a memory address in the managed heap that holds the actual data.
For the reference type, the real object’s reference is utilized to store in the stack memory, while the object itself is stored on the heap memory.

Because reference types reflect the address of the variable rather than the data itself, assigning a reference variable to another does not transmit or copy the data. Instead, it duplicates the reference, pointing to the same heap location as the original item.

In the case of reference type, two variables can reference the same object in the heap memory. As a result, operations on one variable may have an impact on the object that the other variable refers to.

There are two kinds of reference types in C#.

    • built-in reference types
    • user-defined reference types

Built in reference type in C#:   object ,  string ,  dynamic 

User defined reference type in C#:  Class ,  Interface ,  Array ,  delegate 

Example of reference type in C#

Let’s understand the reference type by using the following C# program.

using System;
namespace ReferenceType
{
    // Here, the 'User 'class is a reference type

    class User
    {
        // public field
        public int age = 10;
    }
    class Program
    {

        static void Main(string[] args)
        {
          // Creating object of the 'User' class.
            User user1 = new User();

          // Assign object user1 to the new object user2
            User user2 = user1;

          // Print the value of object user1 and user2
            Console.WriteLine($"user1.age = {user1.age} user2.age ={user2.age}");

          //Changed value of user2 object
            user2.age = 20;

          // Print the value of object user1 and user2
            Console.WriteLine($"user1.age = {user1.age} user2.age ={user2.age}");
        }
    }
}

Let’s execute the above program and see the result.

Reference type output
The output of the above program.

We can see in the above result that changing the value of User2 by 20 also changes the value of User1.
Both objects, of course, point to the same memory region in the managed heap.

Understanding ‘Value type in C#’

In C#, a value type does not carry a reference; instead, it stores the actual value in its own stack memory.
For example, If we assign a value to the integer variable int x = 100, the value 100 will be stored in the same memory area as variable x.

Value type memory allocation
Memory allocation of a value type in stack memory.

Value types variables in C# have their own copy of the data. As a result, when we alter the value of one variable, the original variable is unaffected (except in the case of in, ref and out parameter )

Let’s create the second int variable, y, and assign the first variable’s value to it. The value will be copied from variable ‘x‘ to variable ‘y‘.
CLR (Common Language Runtime) will now generate two different memory locations for x and y in the stack, each of which is fully independent of the other and holds the same value of 100.

Value types assigning values.

Let’s now increase the value of the variable ‘y‘ by one. Because both variables have their own memory allocation, the value of the variable ‘x‘ will not change and will remain the same.

As a result, changes in one variable will have no impact on the other. In C#, these data types are referred to as Value Types.

Consider the following as an example.

Value types memory allocation
Value types memory allocation

We can see that the value of x remains the same and didn’t change after y is incremented by one in the above result
Because the variables ‘x‘ and ‘y‘ are in separate memory regions in the stack and have nothing to do with one another.

Is it true that value types in C# are always saved in stack memory?

It’s a common misperception that value types are always allocated on the stack memory; however, this is not the case. If the variable is a temporary or local variable, or if it is used directly inside a method, the value type will only be allocated on the stack.
If we declare a value type variable at the class level or within another reference type, however, it will be allocated in the GC heap memory.

When a value type variable is no longer in scope, it is automatically freed from memory. The Garbage Collector has no function in releasing the memory.

Value Type Vs Reference Type in C#

      • The value types in C# are stored on the stack memory during compilation, whereas reference types are stored on the managed heap at the run time.
      • The value type variable directly holds the actual value, whereas the reference type variable contains the pointer or reference to a memory location that holds the actual data in the managed heap.
      • Value types in C# are derived from System.ValueType whereas Reference types in C# are derived from System.Object
      • When the value types go out of scope, they are automatically released from the stack memory, whereas the reference types require the use of a garbage collector to be removed from the managed heap.
      • In C#, value types cannot inherit from another class or struct except the interface, whereas the reference types can be inherited from another class or interface.

Note: There is an exceptional case with the String type. Even though the String is a reference type, because it is immutable, it behaves like a value type. When we concatenate or update the value, a new string object with the modified value is created in the managed heap.

To learn more about the string type you can read my previous post Difference between String and StringBuilder in C#

Recommended Articles

    1. Generic Delegates in C# With Examples
    2. IEnumerable Interface in C# with examples
    3. Constructors in C# with Examples
    4. C# Enum | How To Play With Enum in C#?
    5. Properties In C# with examples
    6. 10 Difference between interface and abstract class In C#
    7. What is a delegate in C#? Multicast Delegate with Examples

I hope you liked this post, if you have any questions, please post your question in the below comment section.

Thanks for visiting. 🙂

One Reply to “Value Type and Reference Type in C#”

Leave a Reply