🤔

IndexOutOfRangeException#

Collections are accessed via indices using the indexer syntax: [value]. C#'s indices are zero-indexed. This means that indices begin at 0, and go up to but don't include the length of the collection. [0..Length)

Resolution#

In local scopes#

Ensure that the line pointed to by the stack trace is accessing an index that is within the limits of the collection. The index needs to be 0 or above, and less than the length of the collection.
Common mistakes include:

  • Accessing an empty collection (.Length or .Count is 0).
  • An improperly written for or while loop.
  • Using an index from a different loop, i instead of j for example.

You can use the debugger to step over your code, inspecting variables and execution to assess what is wrong.

Inside lambdas#

If you have code like this:

for (int i = 0; i < values.Length; i++)
{
    values[i].onClick.AddListener(() => values[i].enabled = false);
}

The i in the delegate is not copied inside the for loop, it is created before it, reused, and increased as the counter of the loop. The value in the listener will increase to values.Length at the end of the loop. To fix this, declare a local version of the counter that is used in the delegate:

for (int i = 0; i < values.Length; i++)
{
    int iLocal = i;
    values[i].onClick.AddListener(() => values[iLocal].enabled = false);
}

See anonymous methods and closures for more information.

Notes#

A functioning IDE can autocomplete for loops by typing for and pressing tab/enter. Reverse for loops can be created with forr. This helps prevent basic mistakes.