C# Arrays and Lists
Store related values in order, select a fixed or growable collection, and traverse safely without confusing length, count, and indexes.
Before this lesson
- Types
- Loops
- Methods
- Reference behavior
Create, index, update, and traverse arrays
Add and remove items from List<T>
Choose a collection from required behavior rather than habit
The short answer
An array stores a fixed number of same-typed elements. List<T> stores an ordered same-typed collection that can grow and shrink. Both use zero-based indexes; arrays expose Length and lists expose Count.
A collection keeps one relationship together
Three variables named score1, score2, and score3 can hold three scores, but the structure breaks when a fourth arrives and forces duplicated code for every operation. A collection stores related values under one name and lets a loop apply the same operation to each element.
Arrays and generic lists are strongly typed: an int[] holds integers and a List<string> holds strings. That restriction catches accidental mixtures before runtime and makes every retrieved item useful without a cast.
Arrays have a fixed length
An array's length is chosen when it is created. The elements can be replaced, but the array cannot gain another slot. Indexes start at zero, so an array of length three has indexes 0, 1, and 2. Reading index 3 throws IndexOutOfRangeException.
Arrays fit fixed-shape data, low-level APIs, and cases where an exact size is known. They are also the foundation beneath many collection concepts. Use Length in loop boundaries so the code adapts when the array changes.
using System;
class Program
{
static void Main()
{
string[] weekdays = { "Mon", "Tue", "Wed" };
weekdays[1] = "Tuesday";
for (int index = 0; index < weekdays.Length; index++)
{
Console.WriteLine($"{index}: {weekdays[index]}");
}
}
}Expected output
0: Mon 1: Tuesday 2: Wed
List<T> changes size as the program runs
List<T> is a generic type; T stands for the element type supplied between angle brackets. Add appends an item, Insert places one at an index, Remove removes the first equal item, RemoveAt removes by index, and Count reports the number of elements currently present.
Removing by value and removing by position express different intentions. Remove returns false when the value was not found. RemoveAt throws when the index is invalid. Validate externally supplied indexes rather than letting a user select an arbitrary position unchecked.
List<string> tasks = new List<string>();
tasks.Add("Reply to email");
tasks.Add("Review invoice");
tasks.Insert(1, "Book meeting room");
tasks.Remove("Reply to email");
foreach (string task in tasks)
{
Console.WriteLine(task);
}Expected output
Book meeting room Review invoice
Choose from operations and constraints
Use an array when size is fixed or an API specifically expects one. Use List<T> for most ordered application data that changes over time. Neither is ideal for every lookup: repeatedly scanning thousands of items by key may call for a dictionary, which comes next.
Both arrays and lists are reference types. Assigning one variable to another does not clone the elements; both variables reach the same collection. To make a shallow list copy, construct a new List<T> from the existing sequence. If elements are mutable objects, both collections can still reference the same element objects.
| Need | Array | List<T> |
|---|---|---|
| Exact fixed size | Natural fit | Possible but unnecessary |
| Frequent add/remove | Requires creating another array | Built-in operations |
| Indexed access | Yes | Yes |
| Element count | Length | Count |
| Pass to array-based API | Direct | Convert with ToArray |
Good habits
- Use foreach when you need values and for when you truly need indexes.
- Do not add or remove list items during its foreach enumeration.
- Check Count before accessing a position that might not exist.
Quick knowledge check
Answer before you reveal.
01What is the last valid index of a list whose Count is 5?
4, because indexing starts at zero.
02Does assigning second = first clone a List<T>?
No. It copies the reference, so both variables point to the same list.
Practice challenge
Now build it without copying.
Build a small reading list. Add four book titles, remove one by value, print numbered entries, and report the final count.
You are done when
- The list can grow without changing a declared size
- Numbering shown to the reader starts at 1 while indexes remain zero-based
- Removal failure is handled or reported
Stretch: Create a second list as a copy, change only the copy's membership, and print both counts to demonstrate separate list containers.
Open challenge in playgroundLesson checkpoint
One small step locks it in
Mark this lesson complete, then keep the momentum going.
Clear up the details
Frequently asked questions
Why does an array use Length while List uses Count?
They are different APIs with different historical and interface conventions. Remember the behavior: array capacity is fixed; list membership count changes.
What is a multidimensional array?
It uses more than one index, such as int[,] for a rectangular grid. Jagged arrays are arrays whose elements are arrays and can have different row lengths.
Should I expose a List directly from a class?
Often no. Exposing a mutable list lets callers bypass rules. Return a read-only view or provide focused methods when the owning type must protect invariants.