C# List<T> and Common List Operations

A C# List<T> is a generic collection that stores an ordered sequence of elements. Unlike an array, a list can grow or shrink as elements are added and removed.

A list preserves the insertion order of its elements, supports zero-based indexing, and can contain duplicate values. All elements in a list must be compatible with the type specified by T.

The List<T> class is available in the System.Collections.Generic namespace.

</>
Copy
List<T> listName = new List<T>();

Key Features of C# List<T>

  • Stores elements of a specified type.
  • Maintains elements in a defined order.
  • Supports zero-based index access.
  • Allows duplicate elements.
  • Automatically expands its internal storage when required.
  • Provides methods for adding, searching, sorting, and removing elements.

Initialize a C# List

You can create an empty list and then add elements using the Add() method.

Example 1 – Initialize an Empty List and Add Elements

In this example, we will define a list and then add elements to it, thus initializing the list with some elements.

Program.cs

</>
Copy
using System.Collections.Generic;

namespace CSharpExamples {

    class Program {
        static void Main(string[] args) {
            var names = new List<string>();  
            names.Add("Mack");
            names.Add("Daisy");
            names.Add("Ward");
        }
    }
}

Here, names is inferred as a List<string>. The list initially contains no elements, and each call to Add() appends one value to the end.

Example 2 – Initialize a C# List with Values

We can also define a C# list with initial values. In the following example, we will initialize the list during its declaration itself.

Program.cs

</>
Copy
using System.Collections.Generic;

namespace CSharpExamples {

    class Program {
        static void Main(string[] args) {
            var names = new List<string>() {"Mack", "Daisy", "Ward"};
        }
    }
}

This collection-initializer syntax creates the list and supplies its initial elements in one statement.

Access C# List Elements by Index

List indexes start at 0. The first element is at index 0, the second is at index 1, and the last element is at Count - 1.

</>
Copy
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var names = new List<string>() { "Mack", "Daisy", "Ward" };

        Console.WriteLine(names[0]);
        Console.WriteLine(names[2]);
    }
}

Output

Mack
Ward

Accessing an index less than zero or greater than or equal to Count throws an ArgumentOutOfRangeException.

Print All Elements in a C# List

You can use a foreach loop to read each element in a list in order.

In this example, we will initialize a list, and print the elements of this list using foreach function.

Program.cs

</>
Copy
using System;
using System.Collections.Generic;

namespace CSharpExamples {

    class Program {
        static void Main(string[] args) {
            var names = new List<string>() {"Mack", "Daisy", "Ward"};
            foreach( var name in names) {
                Console.WriteLine(name);
            }
        }
    }
}

Output

PS D:\workspace\csharp\HelloWorld> dotnet run
Mack
Daisy
Ward

Use a for loop instead when the index is required during iteration.

</>
Copy
for (int i = 0; i < names.Count; i++)
{
    Console.WriteLine($"{i}: {names[i]}");
}

Modify an Element in a C# List

You can use index like in an array to modify the elements of a list.

In the following example, we will initialize a list with some elements, and then modify the element at index 1 with a new value.

Program.cs

</>
Copy
using System;
using System.Collections.Generic;

namespace CSharpExamples {

    class Program {
        static void Main(string[] args) {
            var names = new List<string>() {"Mack", "Daisy", "Ward"};
            names[1] = "Fitz";
            foreach( var name in names) {
                Console.WriteLine(name);
            }
        }
    }
}

Output

PS D:\workspace\csharp\HelloWorld> dotnet run
Mack
Fitz
Ward

Add One or More Elements to a C# List

Use Add() to append one element and AddRange() to append several elements from another compatible collection.

</>
Copy
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var names = new List<string>() { "Mack" };

        names.Add("Daisy");
        names.AddRange(new[] { "Ward", "Fitz" });

        foreach (string name in names)
        {
            Console.WriteLine(name);
        }
    }
}

Output

Mack
Daisy
Ward
Fitz

Insert an Element at a Specific List Index

The Insert(index, item) method places an element at a specified index. Existing elements at and after that index move one position to the right.

</>
Copy
var names = new List<string>() { "Mack", "Ward" };
names.Insert(1, "Daisy");

After the insertion, the list contains Mack, Daisy, and Ward.

Remove a C# List Element by Index

You can use List.RemoveAt(int index) to remove an element from List using index.

In the following example, we have list of elements, and we will delete the element present at index 1 using RemoveAt() method.

Program.cs

</>
Copy
using System;
using System.Collections.Generic;

namespace CSharpExamples {

    class Program {
        static void Main(string[] args) {
            var names = new List<string>() {"Mack", "Daisy", "Ward"};
            names.RemoveAt(1);
            foreach( var name in names) {
                Console.WriteLine(name);
            }
        }
    }
}

Output

PS D:\workspace\csharp\HelloWorld> dotnet run
Mack
Ward

The index must be within the list bounds. Otherwise, RemoveAt() throws an ArgumentOutOfRangeException.

Remove a C# List Element by Value

You can use List.Remove(object) to remove the first occurrence of element from List.

In the following example, we will remove the element from List based on value using Remove() method.

Program.cs

</>
Copy
using System;
using System.Collections.Generic;

namespace CSharpExamples {

    class Program {
        static void Main(string[] args) {
            var names = new List<string>() {"Mack", "Daisy", "Ward"};
            names.Remove("Daisy");
            foreach( var name in names) {
                Console.WriteLine(name);
            }
        }
    }
}

Output

PS D:\workspace\csharp\HelloWorld> dotnet run
Mack
Ward

The generic signature is Remove(T item). It returns true when an element is removed and false when the value is not found.

</>
Copy
bool removed = names.Remove("Daisy");
Console.WriteLine(removed);

Remove Multiple Elements from a C# List

Use RemoveAll() to remove every element that matches a condition. It returns the number of removed elements.

</>
Copy
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var numbers = new List<int>() { 2, 5, 8, 11, 14 };

        int removedCount = numbers.RemoveAll(number => number % 2 == 0);

        Console.WriteLine($"Removed: {removedCount}");
        Console.WriteLine(string.Join(", ", numbers));
    }
}

Output

Removed: 3
5, 11

Use Clear() when all elements must be removed from the list.

Get the Number of Elements with List.Count

The property List.Count gives the number of elements in the List.

In the following list, we have a list of strings, and we will count the number of elements in this list using List.Count property.

Program.cs

</>
Copy
using System;
using System.Collections.Generic;

namespace CSharpExamples {

    class Program {
        static void Main(string[] args) {
            var names = new List<string>() {"Mack", "Daisy", "Ward"};
            int listLength = names.Count;
            Console.WriteLine("Length of the list is : "+listLength);
        }
    }
}

Output

PS D:\workspace\csharp\HelloWorld> dotnet run
Length of the list is : 3

Use Count, not Length, to get the number of elements in a List<T>. Arrays use the Length property.

Check Whether a C# List Contains a Value

The Contains() method returns a Boolean value indicating whether the list contains a matching element.

</>
Copy
var names = new List<string>() { "Mack", "Daisy", "Ward" };

if (names.Contains("Daisy"))
{
    Console.WriteLine("Daisy is in the list.");
}

Use IndexOf() when the position of the first matching element is also required. It returns -1 when no match is found.

Find Elements in a C# List

The Find() method returns the first element that matches a condition, while FindAll() returns a new list containing every matching element.

</>
Copy
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var numbers = new List<int>() { 4, 7, 10, 13, 16 };

        int firstEven = numbers.Find(number => number % 2 == 0);
        List<int> evenNumbers = numbers.FindAll(number => number % 2 == 0);

        Console.WriteLine(firstEven);
        Console.WriteLine(string.Join(", ", evenNumbers));
    }
}

Output

4
4, 10, 16

Sort and Reverse a C# List

The Sort() method arranges the elements using their default comparer. The Reverse() method reverses the current order.

</>
Copy
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var numbers = new List<int>() { 30, 10, 20 };

        numbers.Sort();
        Console.WriteLine(string.Join(", ", numbers));

        numbers.Reverse();
        Console.WriteLine(string.Join(", ", numbers));
    }
}

Output

10, 20, 30
30, 20, 10

Calling Sort() changes the original list. Create a copy first when the original order must be preserved.

Convert Between a C# List and an Array

Use ToArray() to create an array from a list. Use the List<T> constructor to create a list from an array or another compatible collection.

</>
Copy
string[] nameArray = { "Mack", "Daisy", "Ward" };

var nameList = new List<string>(nameArray);
string[] copiedArray = nameList.ToArray();

C# List Count and Capacity

Count is the number of elements currently stored in the list. Capacity is the number of elements the internal storage can hold before it must be resized.

PropertyMeaning
CountNumber of elements currently in the list.
CapacityNumber of elements the list can currently hold without resizing its internal storage.

You can supply an initial capacity when the approximate number of elements is known:

</>
Copy
var numbers = new List<int>(100);

This creates an empty list with capacity reserved for 100 integers. Its Count is still 0.

C# List Methods and Properties Reference

MemberPurpose
Add(item)Adds one element to the end of the list.
AddRange(collection)Adds all elements from another collection.
Insert(index, item)Inserts an element at a specified index.
Remove(item)Removes the first matching element.
RemoveAt(index)Removes the element at a specified index.
RemoveAll(predicate)Removes all elements matching a condition.
Clear()Removes every element.
Contains(item)Checks whether an element exists.
IndexOf(item)Returns the index of the first matching element.
Find(predicate)Returns the first matching element.
FindAll(predicate)Returns all matching elements in a new list.
Sort()Sorts the list in place.
Reverse()Reverses the element order in place.
CountReturns the current number of elements.
ToArray()Copies the list elements into a new array.

C# List<T> Compared with an Array

FeatureList<T>Array
SizeCan grow and shrink.Fixed after creation.
Element accessZero-based index.Zero-based index.
Element countCountLength
Add and remove methodsBuilt-in methods such as Add() and Remove().No direct resizing methods.
Best suited forCollections whose number of elements may change.Collections with a known, fixed size.

Common C# List Errors to Avoid

  • Do not access an index outside the range from 0 to Count - 1.
  • Do not add or remove elements inside a foreach loop over the same list.
  • Use Count for a list and Length for an array.
  • Remember that Remove() removes only the first matching value.
  • Remember that methods such as Sort(), Reverse(), and Clear() modify the original list.
  • Check the Boolean return value from Remove() when the program must know whether an element was found.

Frequently Asked Questions About C# List<T>

Can a C# List contain duplicate values?

Yes. A List<T> can contain duplicate elements. Use a set-based collection such as HashSet<T> when values must be unique.

How do you get the last element of a C# List?

For a non-empty list, access the last element with list[list.Count - 1]. Check that Count is greater than zero before doing so.

What is the difference between Remove() and RemoveAt()?

Remove(value) deletes the first matching value and returns a Boolean result. RemoveAt(index) deletes the element at a specified zero-based index.

Can a C# List store different data types?

A strongly typed List<T> stores elements compatible with its declared type. For example, a List<string> stores strings. A list declared with a shared base type or interface can store different derived types that satisfy that declaration.

Is C# List thread-safe?

No. Concurrent reads are safe only while the collection is not being modified. Applications that read and write the same list from multiple threads must provide synchronization or use an appropriate concurrent collection.

C# List Tutorial Editorial Review Checklist

  • Confirm that every example imports System.Collections.Generic.
  • Verify that list indexes are described as zero-based.
  • Distinguish Count from an array’s Length property.
  • Confirm that Remove() is described as removing only the first matching element.
  • State whether each demonstrated method modifies the original list or returns a new collection.
  • Check that examples do not modify a list while iterating over it with foreach.

Summary of C# List Operations

In this C# Tutorial, we learned how to create and initialize a List<T>, access and modify elements, add and remove values, count elements, search a list, sort its contents, and convert between lists and arrays.