Skip to content
Theory · Arrays · lesson 4 of 9

An array is a reference

In the theme on variables, assignment copied the value: after b = a and a = 7, b still held the old number. With arrays the same assignment behaves differently:

C#
int[] a = [1, 2, 3];
int[] b = a;
b[0] = 10;
Console.WriteLine(a[0]); // 10
Console.WriteLine(b[0]); // 10

Let's go through it line by line:

  1. int[] a = [1, 2, 3]; creates an array and gives it the name a.
  2. int[] b = a; does not create a second array. Now the same array has two names: a and b.
  3. b[0] = 10; changes the first element of this one array.
  4. That is why a[0] is 10 too: a and b show the same thing.

Back to the lockers. The row of lockers stands in the changing room, and in your hand is a key to that row. An array variable is the key, not the lockers themselves. The line int[] b = a; cuts a copy of the key: there are now two keys, but still one row. Open a locker with the first key and put something in: with the second key you find it in the same place.

The variable holds a reference

While a program runs, all its values, from numbers to arrays, are kept in the computer's memory: that is the changing room where the lockers stand. The array itself sits in memory apart from the variable. The variable holds a reference: a value the program uses to find the array in memory. That is the key to the row of lockers.

Types whose variables hold a reference are called reference types, and arrays are a reference type. int, double and bool, on the other hand, are value types: their variable holds the value itself.

Assignment copies what the variable holds. For an int that is the number itself, for an array it is the reference. So b = a copies the key, not the lockers.

In the widget, an array variable shows an arrow instead of a value: → [1, 2, 3] means "leads to an array with these elements". Press "Next step" and read the caption: it says whether the names share one array.

LiveTwo names, one arraystep 1 of 10 · frames: 1

An array is created, and a gets a reference to it.

The step caption says whether the names share one array

While two variables hold one reference, a write through either name shows through the other. A method that receives an array gets one more name for the same array. The names part ways only when one of them is assigned a different array.

The key can be changed

Here the key picture is not quite right. A real key fits one lock forever. A reference variable, though, can be assigned a reference to another array, and from then on it leads there. The new array can have any length: the type int[] sets no length; only the array itself has one.

After b = [7, 8, 9], b holds a key to a new row, while the key in a still opens the old one. The old array does not change: assigning a variable does not touch the elements.

An array as a method parameter

A method parameter gets a copy of the argument, so a method cannot change the variable passed to it. For an array the rule is the same, only what gets copied is the reference:

C#
int[] prices = [100, 250, 80];
Discount(prices);
Console.WriteLine(prices[1]); // 225
Replace(prices);
Console.WriteLine(prices[1]); // 225

void Discount(int[] nums)
{
    nums[1] = nums[1] - 25;
}

void Replace(int[] nums)
{
    nums = [0, 0, 0];
}

Let's go through both calls:

  1. Discount(prices) copies the reference in prices into the parameter nums: the method has its own key to the same array.
  2. nums[1] = nums[1] - 25 changes an element of the shared array, so after the call prices[1] is 225.
  3. Replace(prices) also gets a copy of the reference, but puts a reference to a new array into nums. Only the copy of the key changes.
  4. prices still leads to the old array, and 225 is printed again.

Interviewers like to ask this: can a method change an array passed to it? The answer has two parts:

  • its elements, yes: the method gets a copy of the reference and changes the same array;
  • the caller's variable itself, no: assigning to the parameter changes only the copy of the reference.

With ref int[] nums, the method would get the variable prices itself and could put a reference to a new array into it. Without ref, an array, like an int, is passed by value, not by reference: what gets copied is the reference the variable holds.

A real copy

Sometimes you need a second row of lockers with the same things in it, to change the copy and leave the original alone. For that you create a new array of the same length and copy the elements into it with Array.Copy:

C#
int[] original = [1, 2, 3];
int[] copy = new int[original.Length];
Array.Copy(original, copy, original.Length);
copy[0] = 10;
Console.WriteLine(original[0]); // 1
Console.WriteLine(copy[0]);     // 10

Array.Copy(original, copy, original.Length) copies from original into copy as many elements as the third argument says. After that the arrays share no elements, and a write to copy leaves original alone.

Common mistake

Two arrays with the same elements were compared with ==:

C#
int[] a = [1, 2, 3];
int[] b = [1, 2, 3];
bool same = a == b; // ✗
Console.WriteLine(same); // False

The program compiles and prints False, even though the elements are the same. For arrays, == compares references: it checks whether this is one array. Here there are two arrays, like two rows of lockers holding the same things. To compare the contents, you check the lengths and then the elements one by one in a loop.

Key points

  • An array variable holds a reference to the array, not the elements themselves: arrays are a reference type.
  • int[] b = a; copies the reference: the array gets two names, and a write through b shows through a.
  • A method that receives an array can change its elements, but assigning to the parameter does not change the caller's variable.
  • A real copy takes a new array and Array.Copy; == on arrays checks whether they are one array.