.NET Academy

List<T>: the everyday collection

Store, grow, search and reorder sequences of items with List<T>.

11 min read

You will learn

  • Create lists and add, insert and remove items
  • Search and sort lists
  • Know when to use a list instead of an array
  • Avoid modifying a list while looping over it

Arrays that grow

Arrays have a fixed size. Most real data doesn't: a shopping cart, the lines of a file, search results. List<T> is the collection you'll use more than any other — an ordered sequence that grows and shrinks as needed.

var cart = new List<string>();      // empty
cart.Add("Coffee");
cart.Add("Bread");
cart.Add("Milk");
 
Console.WriteLine(cart.Count);      // 3
Console.WriteLine(cart[0]);         // Coffee — indexes work like arrays

Create one with initial items:

var primes = new List<int> { 2, 3, 5, 7 };
List<string> colors = ["red", "green"];          // C# 12 collection expression
var copy = new List<int>(primes);                 // an independent copy

Adding and removing

MethodEffect
Add(item)Append at the end
AddRange(items)Append several
Insert(index, item)Insert at a position, shifting the rest
Remove(item)Remove the first matching item (returns bool)
RemoveAt(index)Remove at a position
RemoveAll(condition)Remove every item matching a condition (returns the count)
Clear()Remove everything
cart.Insert(0, "Eggs");                   // Eggs, Coffee, Bread, Milk
cart.Remove("Bread");                     // Eggs, Coffee, Milk
cart.RemoveAll(item => item.StartsWith("M"));   // Eggs, Coffee

item => item.StartsWith("M") is a lambda — a small inline function. You'll learn them properly in Track 4.

Searching

cart.Contains("Coffee");                 // true
cart.IndexOf("Coffee");                  // 1, or -1 if missing
cart.Find(item => item.Length > 4);      // first match, or null
cart.Exists(item => item == "Tea");      // false

Sorting and reordering

var scores = new List<int> { 70, 95, 82 };
scores.Sort();          // 70, 82, 95 — in place
scores.Reverse();       // 95, 82, 70
 
var people = new List<Person> { ... };
people.Sort((a, b) => a.Age.CompareTo(b.Age));   // sort by a custom rule

Lists vs arrays

Array T[]List<T>
SizeFixedGrows and shrinks
Count propertyLengthCount
Add / Remove✗✓
Indexing x[i]✓✓
Best forFixed-size data, performance-critical codeAlmost everything else

Under the hood, a list stores items in an array. When it's full, it allocates a bigger one (double the size) and copies the items over — so Add is fast on average.

Don't modify a list while looping over it

foreach (var item in cart)
{
    if (item == "Milk") cart.Remove(item);   // 💥 InvalidOperationException
}

Instead, use RemoveAll, loop backwards with for (removing doesn't shift the items you haven't visited yet), or build a new list.

Expose read-only views

If a class owns a list, don't let outsiders modify it directly. Expose IReadOnlyList<T> and provide methods like AddItem that keep the class in control.

Try it

Program.cs
Loading editor…

C# runtime not loaded

Key takeaways

  • List<T> is an ordered, resizable collection with index access.
  • Add, Insert, Remove, RemoveAt, RemoveAll change it; Contains, IndexOf, Find search it.
  • Use Count, not Length.
  • Never add or remove items inside a foreach over the same list.

Exercise

Evens returns a NEW list with only the even numbers. InsertSorted inserts a value into an already-sorted list at the right position, keeping it sorted. RemoveAllOf removes every occurrence of a value and returns how many were removed.

Program.cs
Loading editor…

C# runtime not loaded

Hint 1

InsertSorted: find the index of the first element bigger than value (or use sorted.Count if there's none), then sorted.Insert(index, value).

Hint 2

RemoveAllOf: List has a RemoveAll method that takes a condition: items.RemoveAll(item => item == value) — it returns the number removed. Or loop backwards with RemoveAt.

Show solution
var numbers = new List<int> { 1, 3, 5 };
InsertSorted(numbers, 4);
Console.WriteLine(string.Join(", ", numbers));

List<int> Evens(List<int> numbers)
{
    var result = new List<int>();
    foreach (var n in numbers)
    {
        if (n % 2 == 0) result.Add(n);
    }
    return result;
}

void InsertSorted(List<int> sorted, int value)
{
    int index = 0;
    while (index < sorted.Count && sorted[index] < value)
    {
        index++;
    }
    sorted.Insert(index, value);
}

int RemoveAllOf(List<string> items, string value)
{
    int removed = 0;
    for (int i = items.Count - 1; i >= 0; i--)
    {
        if (items[i] == value)
        {
            items.RemoveAt(i);
            removed++;
        }
    }
    return removed;
}

Quiz

4 questions · 3 correct to pass
  1. 1.What's the main advantage of List<T> over an array?

  2. 2.Which property gives the number of items in a List<T>?

  3. 3.What happens if you call list.Remove(item) inside a foreach over the same list?

  4. 4.What does `list.IndexOf("x")` return if "x" isn't in the list?

To complete this lesson

  • ○ Solve the exercise
  • ○ Pass the quiz (3/4 correct)