Understanding Arrays as Reference Types in C#

Arrays as Reference Types

In programming, it's important to understand the behavior of arrays. In most programming languages including C#, arrays are treated as reference types. This article will explore what that means and how to use that knowledge effectively.

Value Types vs Reference Types

In C#, data types are categorized into two main types:

  • Value types : Store actual values directly. Examples : int, float, bool, struct
  • Reference types : Store memory addresses instead of the actual values. Examples: class, string, array, delegate

Arrays, like classes, are reference types. When you assign one array variable to another, you're copying the reference, not the actual data.

Example: Arrays as Reference Types

using System;
class Program
{
    static void Main()
    {
        int[] array1 = { 1, 2, 3 };
        int[] array2 = array1; // Copy reference
        array2[0] = 100;
        Console.WriteLine(array1[0]); // Outputs 100
    }
}

Output:

100

As you can see, modifying array2 affects array1, because both point to the same memory location.

Potential Pitfalls

Since arrays are reference types, modifying them through one variable also changes the data seen by another. This can lead to bugs if you're not careful. To help prevent that, you can use techniques like readonly.

Protecting the Array with readonly
class Example
{
    private readonly int[] numbers = { 1, 2, 3 };

    public void ModifyArray()
    {
        // numbers = new int[3]; // Error!
        numbers[0] = 100; // OK: individual element
    }
}

readonly prevents reassignment of the array reference, but not the modification of individual elements.

Passing Arrays to Functions

void ModifyArray(int[] arr)
{
    arr[0] = 100;
}

int[] numbers = { 1, 2, 3 };
ModifyArray(numbers);
Console.WriteLine(numbers[0]); // 100

The array is modified because only the reference is passed.

Reassigning Arrays Inside Functions

void ReassignArray(int[] arr)
{
    arr = new int[] { 10, 20, 30 }; // New reference
}

int[] numbers = { 1, 2, 3 };
ReassignArray(numbers);
Console.WriteLine(numbers[0]); // 1

The reassignment has no effect on the original array, because it only updates the local copy of the reference.

Returning Arrays: Shallow Copy

public int[] GetArray(int[] array)
{
    int[] tempArray = array;
    return tempArray; // Still points to the same array
}

Returned arrays still point to the original data unless you explicitly clone or copy them.

Use of new Operator

int[] numbers = { 1, 2, 3, 4, 5 };

// Equivalent to:
int[] numbers = new int[] { 1, 2, 3, 4, 5 };

Even without explicitly writing new, arrays are created on the heap and referenced via a variable on the stack.

Summary

Since arrays are reference types, assignments only copy memory addresses—not the actual data.

  • When passed to functions
  • When returned
  • When assigned to another variable

This behavior avoids unnecessary memory duplication and helps with performance—but only if you understand and use it wisely.

Popular posts from this blog

Setting Up a Basic Follow Camera with Cinemachine 3.x

Understanding and Using ? (nullable) in C#