ZetCode

C# List Remove

last modified November 6, 2026

In this article we show how to delete list elements in C#.

C# list is a collection of elements of the same type. The elements can be accessed by index.

We can delete list elements with Remove, RemoveAll, RemoveAt, RemoveRange and Clear methods. These methods modify the list in place. Removing an element shifts all the following elements one position to the left, so removing from the beginning of a large list is an O(n) operation.

C# List Remove

The Remove method removes the first occurrence of a specific object from the list.

public bool Remove(T item)

It returns true if item is successfully removed; otherwise, false.

Program.cs
List<string> words = [ "sky", "cup", "new", "war", "wrong",
    "crypto", "forest", "water", "cup" ];

string word = "sky";

RemoveWord(word);
RemoveWord(word);

words.Remove("cup");

Console.WriteLine(string.Join(' ', words));

void RemoveWord(string word)
{
    if (words.Remove(word))
    {
        Console.WriteLine($"{word} removed");
    }
    else
    {
        Console.WriteLine($"failed to remove {word}");
    }
}

In the program, we define a list of strings. We use the Remove method to delete a word.

RemoveWord(word);
RemoveWord(word);

The first call removes the word; the second call fails, because the word is no longer in the list.

words.Remove("cup");

The list contains the word cup twice. Only the first occurrence is removed.

$ dotnet run
sky removed
failed to remove sky
new war wrong crypto forest water cup

C# List Remove objects

The Remove method finds the item using the default equality comparer of the type. For records, the equality is value-based; for classes, it is reference-based unless the class overrides Equals.

Program.cs
List<User> users =
[
    new("John Doe", "gardener"),
    new("Roger Roe", "driver"),
    new("Lucy Smith", "teacher")
];

bool r1 = users.Remove(new User("Roger Roe", "driver"));
Console.WriteLine(r1);

List<Product> products = [new("pen"), new("book")];

bool r2 = products.Remove(new Product("pen"));
Console.WriteLine(r2);

Product book = products[1];
bool r3 = products.Remove(book);
Console.WriteLine(r3);

Console.WriteLine(users.Count);
Console.WriteLine(products.Count);

record User(string Name, string Occupation);

class Product(string name)
{
    public string Name { get; } = name;
}

We remove a record and a class instance from two lists.

bool r1 = users.Remove(new User("Roger Roe", "driver"));

A new record with the same values is equal to the stored one, so the user is removed.

bool r2 = products.Remove(new Product("pen"));

The new Product object is a different reference. Since the class does not override Equals, nothing is removed.

Product book = products[1];
bool r3 = products.Remove(book);

With a reference to the stored object, the removal succeeds.

$ dotnet run
True
False
True
2
1

C# List RemoveAt

The RemoveAt method removes the element at the specified index of the list.

public void RemoveAt(int index)

This is the syntax.

Program.cs
List<string> words = [ "sky", "cup", "new", "war", "wrong",
    "crypto", "forest", "water", "cup" ];

Console.WriteLine(string.Join(' ', words));

words.RemoveAt(0);
words.RemoveAt(5);
words.RemoveAt(words.Count - 1);

Console.WriteLine(string.Join(' ', words));

try
{
    words.RemoveAt(10);
}
catch (ArgumentOutOfRangeException e)
{
    Console.WriteLine(e.Message);
}

In the program we remove three elements with RemoveAt.

words.RemoveAt(0);
words.RemoveAt(5);

The first element is removed. The indexes of the remaining elements are shifted, so the second call removes the word forest, which was originally at index six.

words.RemoveAt(words.Count - 1);

This removes the last element. Removing from the end of the list is fast, because no elements need to be shifted.

words.RemoveAt(10);

An invalid index throws an ArgumentOutOfRangeException.

$ dotnet run
sky cup new war wrong crypto forest water cup
cup new war wrong crypto water
Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')

C# List RemoveAll

The RemoveAll method removes all the elements that match the conditions defined by the specified predicate.

public int RemoveAll(Predicate<T> match)

It returns the number of elements removed from the list.

Program.cs
List<string> words = [ "sky", "cup", "new", "war", "wrong",
    "crypto", "forest", "water", "cup" ];

Console.WriteLine(string.Join(' ', words));

int n = words.RemoveAll(e => e.StartsWith('w'));

Console.WriteLine($"{n} elements removed");
Console.WriteLine(string.Join(' ', words));

List<int> vals = [1, -2, 3, 0, -5, 6, -7];
vals.RemoveAll(e => e < 0);
Console.WriteLine(string.Join(' ', vals));

We remove all words that start with 'w'. Then we print the number of words deleted. Finally, we remove negative values from a list of integers.

int n = words.RemoveAll(e => e.StartsWith('w'));

We pass a predicate in the form of a lambda expression to the RemoveAll method. The method makes a single pass over the list, which is more efficient than calling Remove repeatedly.

$ dotnet run
sky cup new war wrong crypto forest water cup
3 elements removed
sky cup new crypto forest cup
1 3 0 6

C# List RemoveRange

The RemoveRange method removes a range of elements from the list.

public void RemoveRange(int index, int count)

The parameters are the starting index of the range of elements to remove and the number of elements to remove.

Program.cs
List<string> words = [ "sky", "cup", "new", "war", "wrong",
    "crypto", "forest", "water", "cup" ];

Console.WriteLine(string.Join(' ', words));

words.RemoveRange(0, 4);
Console.WriteLine(string.Join(' ', words));

words.RemoveRange(words.Count - 2, 2);
Console.WriteLine(string.Join(' ', words));

In the example, we remove four elements, starting from the beginning. Then we remove the last two elements.

$ dotnet run
sky cup new war wrong crypto forest water cup
wrong crypto forest water cup
wrong crypto forest

C# List Clear

The Clear method removes all elements from the list.

Program.cs
List<string> words = [ "sky", "cup", "new", "war", "wrong",
    "crypto", "forest", "water", "cup" ];

Console.WriteLine($"Count: {words.Count}, Capacity: {words.Capacity}");

words.Clear();
Console.WriteLine($"Count: {words.Count}, Capacity: {words.Capacity}");

words.TrimExcess();
Console.WriteLine($"Count: {words.Count}, Capacity: {words.Capacity}");

The program deletes all words with Clear. We check the number of elements with Count.

words.TrimExcess();

Clear sets the count to zero, but it keeps the allocated internal array. The Capacity property shows its size. The TrimExcess method releases the unused memory.

$ dotnet run
Count: 9, Capacity: 9
Count: 0, Capacity: 9
Count: 0, Capacity: 0

C# List removing elements while iterating

A list must not be modified while it is being enumerated with foreach.

Program.cs
List<int> vals = [1, 2, 3, 4, 5, 6, 7, 8];

try
{
    foreach (var e in vals)
    {
        if (e % 2 == 0)
        {
            vals.Remove(e);
        }
    }
}
catch (InvalidOperationException e)
{
    Console.WriteLine(e.Message);
}

Console.WriteLine(string.Join(' ', vals));

List<int> nums = [1, 2, 3, 4, 5, 6, 7, 8];

for (int i = nums.Count - 1; i >= 0; i--)
{
    if (nums[i] % 2 == 0)
    {
        nums.RemoveAt(i);
    }
}

Console.WriteLine(string.Join(' ', nums));

We try to remove even numbers in a foreach loop.

foreach (var e in vals)
{
    if (e % 2 == 0)
    {
        vals.Remove(e);
    }
}

After the first removal, the next call to the enumerator throws an InvalidOperationException. Only the number 2 is removed.

for (int i = nums.Count - 1; i >= 0; i--)

A for loop going backwards is safe; removing an element does not change the indexes of the elements we have yet to visit. In most cases, RemoveAll is a simpler solution.

$ dotnet run
Collection was modified; enumeration operation may not execute.
1 3 4 5 6 7 8
1 3 5 7

C# List removing duplicates

There is no dedicated method for removing duplicate elements, but we can combine existing ones.

Program.cs
List<string> words = ["sky", "cup", "sky", "war", "cup", "sky", "pen"];

List<string> unique = words.Distinct().ToList();
Console.WriteLine(string.Join(' ', unique));

var seen = new HashSet<string>();
words.RemoveAll(e => !seen.Add(e));
Console.WriteLine(string.Join(' ', words));

We remove duplicate words in two ways.

List<string> unique = words.Distinct().ToList();

The LINQ Distinct method creates a new list with unique elements.

var seen = new HashSet<string>();
words.RemoveAll(e => !seen.Add(e));

To modify the list in place, we use RemoveAll with a HashSet. The Add method returns false for an element that has already been seen; such elements are removed. The first occurrence of each word is kept.

$ dotnet run
sky cup war pen
sky cup war pen

C# filtering a list with LINQ

If we want to keep the original list intact, we use LINQ's Where method instead. It returns a new sequence without the unwanted elements.

Program.cs
List<string> words = [ "sky", "cup", "new", "war", "wrong",
    "crypto", "forest", "water", "cup" ];

List<string> filtered = words.Where(e => !e.StartsWith('w')).ToList();

Console.WriteLine(string.Join(' ', filtered));
Console.WriteLine(string.Join(' ', words));

We create a new list with words that do not start with 'w'. The original list is unchanged.

$ dotnet run
sky cup new crypto forest cup
sky cup new war wrong crypto forest water cup

Source

List class - language reference

In this article we have showed how to remove list elements in C#.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all C# tutorials.