CodeOath
← All posts
C#65 min total · 17 parts

C# Fundamentals: Value Types, Reference Types, Boxing, and the Type System

Contents — Part 10 of 17: Arrays and Collections Are Reference Types
Part 10 of 17 · ~1 min

Arrays and Collections Are Reference Types

Arrays are always reference types in C#, even an array of a value type — the array object itself is on the heap; what varies is whether its elements are stored inline (value type) or as references (reference type):

int[] arr1 = { 1, 2, 3 };
int[] arr2 = arr1;
arr2[0] = 99;
Console.WriteLine(arr1[0]); // 99 — arr1 and arr2 reference the same array object

// The elements themselves are stored inline for a value-type array, boxed/referenced for a
// reference-type array — but the array object as a whole is always shared on assignment.

This surprises people coming from the "value types copy" rule in the first section — an int[] is a reference type containing value types, and assigning it copies the reference to the whole array, not a fresh array with copied elements. To actually copy an array's contents, you need an explicit copy operation:

int[] copy = (int[])arr1.Clone();          // shallow copy — a genuinely separate array
int[] copy2 = arr1.ToArray();              // LINQ — also a genuinely separate array
Array.Copy(arr1, copy, arr1.Length);       // another way to get an independent copy

For an array of reference types, even a "copy" made this way only duplicates the array of references — the objects they point to are still shared between the original and the copy (a shallow copy), which matters the moment either array's elements are mutated in place.