When you start working with collections in C#, one of the most useful types you'll run into is the List<T>.
It's flexible, easy to use, and built on top of arrays — but with the added ability to grow and shrink dynamically.
Let's break it down.
What is a List?
A List<T>
is part of the System.Collections.Generic
namespace. It's basically a resizable array that can store elements of any specific type (thanks to generics).
Unlike arrays, you don't need to know how many elements you'll have in advance. You can add, remove, and search for items on the fly.
Example:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<string> names = new List<string>();
names.Add("Alice");
names.Add("Bob");
names.Add("Charlie");
Console.WriteLine("Total names: " + names.Count);
foreach (string name in names)
{
Console.WriteLine(name);
}
}
}
Why Use a List Instead of an Array?
Here's the thing — arrays are fixed-size. Once you define an array of 5 elements, that's it. Lists, on the other hand, manage memory for you. They can automatically grow when you add more items.
Feature | Array | List |
---|
Fixed size | ✅ | ❌ |
Auto resize | ❌ | ✅ |
Type safe | ✅ | ✅ |
Easy to add/remove | ❌ | ✅ |
Index-based access | ✅ | ✅ |
Common List Operations
Let's go through the most-used methods and properties.
1. Adding Items
List<int> numbers = new List<int>();
numbers.Add(10);
numbers.AddRange(new int[] { 20, 30, 40 });
2. Accessing Elements
Console.WriteLine(numbers[0]); // Output: 10
3. Removing Items
numbers.Remove(20); // Removes the first occurrence of 20
numbers.RemoveAt(0); // Removes item at index 0
numbers.Clear(); // Removes all items
4. Searching
bool exists = numbers.Contains(30);
int index = numbers.IndexOf(40);
5. Sorting and Reversing
numbers.Sort();
numbers.Reverse();
6. Iterating
foreach (int n in numbers)
{
Console.WriteLine(n);
}
Generic Power
Lists are generic — meaning they hold elements of one specific type. This avoids runtime casting errors and improves performance.
List<double> prices = new List<double> { 10.5, 20.75, 30.0 };
If you need a collection that holds multiple types, use List<object>
, but it's better to stick with generics whenever possible.
Advanced Features
Capacity and Count
List<int> nums = new List<int>(5);
Console.WriteLine(nums.Capacity); // 5
When the capacity is reached, the list automatically doubles its size internally.
LINQ with Lists
Lists work beautifully with LINQ:
var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();
You can filter, sort, and project data easily — no manual loops required.
When Not to Use a List
While List<T>
covers most use cases, sometimes other collections are better:
LinkedList<T> → frequent insertions/removals in the middle
HashSet<T> → unique values only
Dictionary<TKey, TValue> → key-value pairs
Queue<T> / Stack<T> → FIFO/LIFO operations
Conclusion
List<T>
is the go-to collection in C#. It's simple, efficient, and covers most real-world use cases — from managing a list of users to keeping track of scores in a game. Once you understand how it works, many other collection types will feel familiar.