C# Variables - Value vs. Reference

It is essential that when you learn about variables and data types that you understand the differences between data types and reference types. Every time you create a variable, that variable is allocated storage with the computer’s memory. What is stored in a variables memory allocation is what differentiates a value type variable from a reference type variable.

Value Types

Value type variables store the value of the data in it’s allocated memory space. Visual Studio can allocate the exact amount of space for the value of the variable because value type data types have a set size.

The main Value Types are:

  • Boolean (bool)

  • Character (char)

  • Float

  • Double

  • Decimal

  • Short

  • Integer (int)

  • Long

  • Structures (structs)


In C#, there is another type of object that has a value type data type but allows you to store data that is related to the value of the variable. A “structure” type, often referred to as a “struct” incorporates properties and methods into the type, providing information and functionality to the variable.

The DATETIME data type is a structure that provides you with additional functionality around the DATETIME value. Therefore, DATETIME is considered a value type.

Assigning Value Types with Value Types

Since a value type variable stores the actual value of the data, when you assign the value of one value type variable to another, you are copying the actual data into the second variable.

 static void Main(string[] args)
 int myAge = 38;
 int yourAge = myAge;
 Console.WriteLine($"My age is {myAge}. Your age is {yourAge}.");
 yourAge = 42;
 Console.WriteLine($"My age is {myAge}. Your age is {yourAge}.");

Every INT variable stores the actual value of the data. Therefore, if we change one of the values, the other one remains untouched.

Reference Types

When working with some data types, such as a LIST, Visual Studio can not determine, at the time of creation, how much memory the LIST is going to need. To accommodate this, it will store the value of the data in a section of memory called the “heap” which will allow the LIST to grow as large as it needs to, as long as the computer has the memory for it. The variable you declare will contain a pointer to this location in memory. This pointer is called a "reference.” Like an index in the book that tells you where to find a term you are looking for, the reference stored in the variable tells the application where to find the value it needs.

The main Reference Types are:

  • Arrays

  • Lists

  • Dictionaries

  • Classes

  • String

Assigning Reference Types with Reference Types

You must understand that reference type variables store a pointer to the value, not the value. This fact will come into play every time you set one reference type equal to another. When you do this, both variables are pointing to the same location on the heap. If one of those variables changes the value, it will be reflected in the other variable. The following code demonstrates this.

 string[] names = new string[] 
 { "scott", "john", "bob", "smith" };
 string[] newNames = names;
 newNames[0] = "kathy";
 newNames[1] = "james";
 foreach (string item in names)

When this code is run, you will notice that even though the name changes are for the “newNames” array, the “names” array has been updated as well. Arrays are a reference type variable, meaning “names” and “newNames” are pointing to the same location in memory. Changing one will affect the other.

String Types

Strings are technically classified as a reference type. Since Visual Studio has no idea how large the value of the string will be, it needs to store the value on the heap. The string variable stores a reference to the memory location of that value.

String Comparisons

Typically when you compare the equality of two reference type variables, the comparison is checking to see if the variables are pointing to the same location in memory. With strings, however, the comparison checks are designed to compare the values of the string objects.

Take a look at the following code:

 string name = "Scott";
 string newName = "S";
 newName = newName + "cott";
 Console.WriteLine(name == newName);

Strings are reference types. Therefore we know that the memory location “name” is pointing to is not the same memory location “newName” is referencing. You can verify this by doing a check for reference equality.


We know the references aren’t equal, yet our comparison “name == newName” resolves to TRUE. This functionality was implemented in Visual Studio to make string comparisons more intuitive.

String Are Immutable

Let’s attempt the same functionality we used to demonstrate reference types with a string type.

name = "Scott";
string newName = name;
newName = "John";
Console.WriteLine($"Name = {name} : NewName = {newName} ");

When you run this code, you see that change “newName” did not affect “name” even though a string is a reference type. Strings are “immutable,” meaning they are not allowed to change once the object has been created. Even though this code looks like it’s doing exactly that, Visual Studio is doing something else behind the scenes.

When a line of code is written to change the value of a string, Visual Studio is not changing the value the string is referencing. What is occurring instead is a new location in memory is being created with the new value. The string object is being updated to point to that new location.

This functionality can be demonstrated by using the “ReferenceEquals” method from earlier.

 string name = "Scott";
 string newName = name;
 Console.WriteLine(object.ReferenceEquals(name, newName));
 newName = "John";
 Console.WriteLine(object.ReferenceEquals(name, newName));

The first line will display TRUE, but the second line will display FALSE.

49 views0 comments

Recent Posts

See All