C# Lists: A Practical Introduction

If you’re learning C#, one of the first collection types you’ll encounter is the List.

A List is a dynamic collection that can grow or shrink as your program runs, making it much more flexible than a fixed-size array.

Whether you’re storing names, numbers, products, or custom objects, List<T> provides an easy and efficient way to work with groups of data.

In this guide, you’ll learn how to:

  • Create a List
  • Add items
  • Remove items
  • Insert items
  • Search for items
  • Sort a List
  • Count items
  • Clear a List

What Is a List?

A List<T> is a generic collection that stores multiple objects of the same type.

The T represents the data type stored in the list.

For example:

  • List<string> stores text.
  • List<int> stores integers.
  • List<double> stores decimal numbers.
  • List<Person> stores custom objects.

Unlike arrays, Lists automatically resize as items are added or removed, making them ideal when you don’t know in advance how many items you’ll need to store.


Creating a List

Before using a List, include the collections namespace:

using System.Collections.Generic;

Create an empty list:

List<string> names = new List<string>();

Or initialize it with values:

List<string> names = new()
{
    "Alice",
    "Bob",
    "Charlie"
};

Add()

The Add() method appends a new item to the end of the List.

List<string> fruits = new();

fruits.Add("Apple");
fruits.Add("Orange");
fruits.Add("Banana");

Output

Apple
Orange
Banana

You can call Add() as many times as needed, and the List automatically grows to accommodate new items.


Remove()

Remove() deletes the first occurrence of a specified value.

fruits.Remove("Orange");

Output

Apple
Banana

If the value doesn’t exist, Remove() simply returns false and leaves the List unchanged.


RemoveAt()

RemoveAt() removes an item by its index.

fruits.RemoveAt(0);

Output

Banana

Remember that List indexes begin at 0, so the first item is always located at index 0.


Insert()

Use Insert() to add an item at a specific index.

fruits.Insert(0, "Mango");

Output

Mango
Banana

Existing items automatically shift to make room for the new item.


Contains()

Contains() checks whether a List contains a specific value.

bool hasApple = fruits.Contains("Apple");

Console.WriteLine(hasApple);

Output

False

This method returns either true or false, making it useful for validating user input or preventing duplicate values.


IndexOf()

IndexOf() returns the position of an item within the List.

int index = fruits.IndexOf("Banana");

Console.WriteLine(index);

Output

1

If the item isn’t found, IndexOf() returns -1.


Count

The Count property returns the current number of items stored in the List.

Console.WriteLine(fruits.Count);

Output

2

Unlike arrays, you don’t need to manually keep track of how many items the List contains.


Sort()

The Sort() method arranges items in ascending order.

List<int> numbers = new() { 42, 7, 19, 3 };

numbers.Sort();

Output

3
7
19
42

When sorting strings, Sort() arranges them alphabetically by default.

List<string> animals = new()
{
    "Zebra",
    "Dog",
    "Cat",
    "Elephant"
};

animals.Sort();

Output

Cat
Dog
Elephant
Zebra

Searching a List with Find()

Although Lists provide several search methods, one of the most commonly used is Find().

Find() searches the List using a condition and returns the first matching item.

List<int> numbers = new()
{
    12,
    45,
    8,
    63,
    27
};

int result = numbers.Find(n => n > 40);

Console.WriteLine(result);

Output

45

The expression:

n => n > 40

is called a lambda expression. It tells Find() to return the first number greater than 40.

You can search for virtually any condition.

For example, finding the first even number:

int even = numbers.Find(n => n % 2 == 0);

Console.WriteLine(even);

Output

12

If no matching item is found, Find() returns the default value for the data type (for example, null for reference types or 0 for int).


Clear()

The Clear() method removes every item from the List.

fruits.Clear();

Console.WriteLine(fruits.Count);

Output

0

The List itself still exists—it simply becomes empty and is ready to store new items.


When Should You Use a List?

A List<T> is a great choice whenever:

  • The number of items can change during program execution.
  • You need to frequently add or remove items.
  • You want built-in methods for searching and sorting.
  • You don’t want to manage array sizes manually.

Arrays are useful when the size is fixed, but Lists are generally the preferred collection for most everyday C# programming tasks.


Summary

List<T> is one of the most useful and commonly used collection types in C#. It provides a simple, flexible way to store and manage groups of objects while automatically handling memory allocation as your data grows.

Here’s a quick reference for the methods covered in this article:

MethodPurpose
Add()Adds an item to the end of the List
Remove()Removes the first matching item
RemoveAt()Removes an item by index
Insert()Inserts an item at a specific position
Contains()Checks whether an item exists
IndexOf()Returns the index of an item
Find()Returns the first item matching a condition
Sort()Sorts the List in ascending order
Clear()Removes every item from the List
CountReturns the current number of items

Once you’re comfortable with these methods, you’ll be well prepared to work with Lists in real-world C# applications, from simple console programs to desktop software, web APIs, and ASP.NET Core applications.