Nearly every program holds data in arrays or lists; knowing their trade-offs is basic fluency.
An array has a fixed length set at creation: int[] a = new int[5]; (all zeros) or int[] b = [1, 2, 3];. Access by index from 0; out-of-range access throws IndexOutOfRangeException. a.Length gives the size. Multi-dimensional arrays exist (int[,]), as do jagged arrays (int[][]).
List<T> (in System.Collections.Generic) is the growable workhorse: Add, AddRange, Insert, Remove, RemoveAt, Contains, IndexOf, Sort, and Count for the size. Internally it wraps an array that is doubled when full, so Add is amortized O(1) while Insert(0, x) is O(n).
Collection expressions (C# 12) give one syntax for arrays, lists and spans: List<string> names = ["Ada", "Linus"];. The spread operator .. inlines another collection: [..first, ..second, 99].
Arrays and lists are reference types: assigning one to another variable copies the reference, so both see the same items. Copy explicitly with [..list], list.ToList() or array.ToArray() when you need independent data.
Indices from the end use ^: list[^1] is the last element. Ranges a[1..3] slice arrays (creating a copy) and strings.
Use an array when the size is fixed or for performance-sensitive code; use List<T> everywhere else.
Example
int[] squares = new int[4];
for (int i = 0; i < squares.Length; i++) squares[i] = i * i;
Console.WriteLine(string.Join(",", squares)); // 0,1,4,9
Console.WriteLine(string.Join(",", squares[1..3])); // 1,4
List<string> names = ["Ada", "Linus"];
names.Add("Grace");
names.Insert(0, "Alan");
names.Remove("Linus");
Console.WriteLine($"{names.Count}: {string.Join(" ", names)}"); // 3: Alan Ada Grace
Console.WriteLine(names[^1]); // Grace
var alias = names; // same list
var copy = names.ToList(); // independent copy
alias.Add("Barbara");
Console.WriteLine($"{names.Count} {copy.Count}"); // 4 3
int[] merged = [..squares, 100];
Console.WriteLine(merged.Length); // 5Remember
- Arrays are fixed size; List<T> grows as needed
- Collection expressions [a, b, ..other] work for arrays and lists
- Assignment copies the reference, not the items
- ^1 indexes from the end, a..b slices
Watch out for
- Expecting var b = a; to copy a list; both variables now share one list.