An array holds a fixed number of elements of one type, stored side by side in memory. You choose the length when you create it, you read and write elements by a zero-based index, and the length never changes after that.
Declaring and initializing an array
The type of an array is the element type followed by []. There are several ways to create one:
Output:
90, 0, 0, 72
Ben
2 prices, 3 days
new int[4] fills every element with the default value of the type: 0 for numbers, false for bool, null for strings and other reference types. The short form { "Ana", "Ben" } only works in a declaration; when assigning to an existing variable you need names = new[] { "Dev", "Eli" };.
Length, indexing and the last element
Indexes run from 0 to Length - 1. Length is a property, so it has no parentheses (unlike LINQ's Count() method).
Output:
Count: 5
First: 18
Last: 16
Caught IndexOutOfRangeException
Reading or writing outside the bounds throws IndexOutOfRangeException at run time; the compiler does not catch it. The usual cause is a loop condition written as i <= arr.Length instead of i < arr.Length.
C# 8 and later add index-from-end and range syntax, which is shorter for the last element and for slices:
int last = temps[^1]; // 16
int[] middle = temps[1..4]; // { 21, 25, 19 }, a new array
Looping over an array
A for loop gives you the index; foreach gives you each element and is the clearer choice when you only read.
Output:
4.95 | 13.20 | 3.58
Total: 21.73
The foreach variable is read-only: p = 0; inside the loop is a compile error. To change elements, loop with an index.
Sorting, reversing and searching
The static Array class holds the helpers. Array.Sort sorts in place and returns nothing, so the original order is gone.
Output:
Ascending: 60, 72, 79, 88, 95
Descending: 95, 88, 79, 72, 60
Index of 60: 4
Index of 99: -1
Any above 90: True
First below 75: 72
Ana, ben, chloe
fig, kiwi, banana
Array.IndexOf returns -1 when the value is missing. Array.Find returns the default value of the type (0 here) when nothing matches, which is ambiguous for numbers; use Array.FindIndex when that matters. A descending sort in one call is Array.Sort(scores, (a, b) => b.CompareTo(a)).
If you need the sorted result without touching the original, LINQ returns a new array: var sorted = scores.OrderBy(s => s).ToArray();. See LINQ.
Resizing: an array cannot grow
The length is fixed. Array.Resize creates a new array of the requested size, copies the elements, and updates the variable you pass by ref.
Output:
4
2
True
False
Each resize copies every element. Growing an array one item at a time in a loop is slow and is exactly what List<T> does for you more efficiently, by doubling its internal array.
Arrays are reference types: copying
Assigning an array to another variable copies the reference, not the elements. Both names then point at the same array.
Output:
100
2
0, 100, 2, 3, 0
The same applies when you pass an array to a method: the method can change the caller's elements. Clone, Array.Copy, CopyTo and LINQ's ToArray() all make a shallow copy. For an array of objects, the new array holds references to the same objects, so changing copy[0].Name still changes what original[0] sees.
Comparing arrays with == compares references. To compare contents, use a.SequenceEqual(b) from System.Linq.
2D arrays (multidimensional)
A rectangular grid is declared with a comma inside the brackets. Index it with [row, col].
Output:
Rows: 2
Cols: 3
Length: 6, Rank: 2
. X .
. . X
Length on a 2D array is the total element count (6 for a 2 by 3 grid), which is why nested loops use GetLength(0) and GetLength(1). Rank is the number of dimensions. Three dimensions work the same way: new int[4, 4, 4] and cube[x, y, z]. A foreach over a 2D array visits every element row by row.
Jagged arrays (arrays of arrays)
A jagged array int[][] is an array whose elements are themselves arrays, and each inner array can have its own length. It suits data like "orders per customer" where rows differ in size.
Output:
Customer 0: 2 orders, 20, 35
Customer 1: 1 orders, 12
Customer 2: 4 orders, 8, 15, 40, 22
True
new int[3][] creates the outer array only; each row starts as null, and orders[0][0] before assigning a row throws NullReferenceException. The syntax new int[3][4] is not allowed; you create each row yourself.
Use [,] for a true grid (a board, a matrix, pixels) and [][] when rows have different lengths or you want to swap whole rows.
Array vs List
Array T[] | List<T> | |
|---|---|---|
| Size | Fixed at creation | Grows and shrinks |
| Count | Length property | Count property |
| Add or remove | Not possible (only Array.Resize) | Add, Insert, Remove |
| Multidimensional | [,] and [][] | Only lists of lists |
| Typical use | Known size, lookup tables, buffers | Collections that change |
Converting is one call either way: new List<int>(arr) or arr.ToList(), and list.ToArray(). List<T> is the growable version.
Common mistakes
i <= arr.Lengthin a loop. The last valid index isLength - 1; this throwsIndexOutOfRangeException.- Printing the array directly.
Console.WriteLine(arr)printsSystem.Int32[]; usestring.Join. - Expecting
Array.Sortto return the sorted array. It returnsvoidand sorts in place. - Copying with
=. That copies the reference; useClone()orToArray(). - Using jagged rows before creating them. Each row of
new T[n][]isnulluntil assigned. - Using
Lengthfor rows of a 2D array. It counts every element; useGetLength(0).
Frequently Asked Questions
How do I get the length of an array in C#?
Use the Length property: scores.Length. It is a property, not a method, so there are no parentheses. For a 2D array Length is the total number of elements; use GetLength(0) for the number of rows and GetLength(1) for the number of columns.
How do I sort an array in C#?
Array.Sort(arr) sorts the array in place in ascending order. For descending order, call Array.Reverse(arr) after sorting, or pass a comparison: Array.Sort(arr, (a, b) => b.CompareTo(a)). To get a sorted copy and keep the original, use LINQ: arr.OrderBy(x => x).ToArray().
What is the difference between a 2D array and a jagged array in C#?
A 2D array int[,] is one rectangular block: every row has the same number of columns, and you index it as grid[row, col]. A jagged array int[][] is an array of arrays: each row is a separate array that can have its own length, and you index it as rows[i][j]. Each row of a jagged array must be created before use, or it is null.
Can you change the size of an array in C#?
No. An array's length is fixed when it is created. Array.Resize(ref arr, newSize) looks like it resizes, but it allocates a new array, copies the elements and points your variable at the new one. If the size changes often, use a List<T>.
Why does printing an array show System.Int32[]?
Console.WriteLine(arr) calls arr.ToString(), and arrays do not override it, so you get the type name. Join the elements into one string instead: Console.WriteLine(string.Join(", ", arr)).
Should I use an array or a List in C#?
Use an array when the number of elements is known and fixed, such as the 12 months or a game board. Use List<T> when elements are added or removed over time. Both index in constant time, and a List<T> stores its elements in an array internally.