Syntax
List<Type> list = new List<Type>();Examples
Creating and Adding Elements
Building a List<T> and adding items to it.
List<string> fruits = new List<string>();
fruits.Add("apple");
fruits.Add("banana");
fruits.Add("cherry");
Console.WriteLine(string.Join(", ", fruits)); // apple, banana, cherry
Console.WriteLine(fruits.Count); // 3Accessing and Modifying Elements
Reading, updating, and removing elements by index or value.
List<string> names = new List<string> { "Fola", "Zain", "Jamal" };
Console.WriteLine(names[1]); // Zain
names[1] = "Priya"; // replace element at index 1
Console.WriteLine(string.Join(", ", names));
names.Remove("Jamal"); // remove by value
names.RemoveAt(0); // remove by index
Console.WriteLine(string.Join(", ", names)); // PriyaIterating and Searching
Looping through elements and checking membership.
List<int> numbers = new List<int> { 10, 20, 30 };
foreach (int num in numbers)
{
Console.WriteLine(num);
}
Console.WriteLine(numbers.Contains(20)); // true
Console.WriteLine(numbers.IndexOf(30)); // 2Sorting a List
Using the built-in Sort() method, with an optional custom comparison.
List<int> numbers = new List<int> { 5, 1, 3 };
numbers.Sort();
Console.WriteLine(string.Join(", ", numbers)); // 1, 3, 5
numbers.Sort((a, b) => b.CompareTo(a)); // descending, via a lambda
Console.WriteLine(string.Join(", ", numbers)); // 5, 3, 1Best practices
- Use List<T> as the default resizable collection - it covers the vast majority of everyday collection needs in C#
- Declare the variable using the IList<T> or IEnumerable<T> interface in method signatures so the implementation can vary without changing calling code
- Use Contains() sparingly on large lists - for frequent membership checks, a HashSet<T> is much faster
- Specify an initial capacity (new List<int>(100)) when you know roughly how many elements to expect, to reduce internal resizing
At a glance
- Purpose
- Applications on the .NET platform
- File extension
- .cs
- Runs in
- .NET runtime
- Usually used with
- .NET SDK and libraries
Specifications & further reading
Related C# documentation
Dictionary<TKey, TValue>
Dictionary<TKey, TValue> stores data as key-value pairs, offering fast average-case lookup, insertion, and deletion by key, backed by a hash table. Keys must be unique - adding a value with an existing key throws an exception, while indexer assignment (dict[key] = value) overwrites it instead. Dictionary does not guarantee any particular iteration order.Queue<T> & Stack<T>
Queue<T> is a first-in-first-out (FIFO) collection - items are added with Enqueue() and removed with Dequeue(), just like a real-world line. Stack<T> is last-in-first-out (LIFO) - items are added with Push() and removed with Pop(), like a stack of plates. Both are useful for specific processing orders where a general-purpose List<T> would require extra bookkeeping.HashSet<T>
HashSet<T> is a collection that stores unique elements with no guaranteed ordering, backed by a hash table. Adding a duplicate element has no effect, since HashSet automatically enforces uniqueness. It provides very fast average-case performance for adding, removing, and checking membership, and offers built-in set operations like union, intersection, and difference.foreach & IEnumerable
foreach is C#'s dedicated loop for iterating over any collection that implements IEnumerable<T> - which includes arrays, List<T>, Dictionary<TKey,TValue>, and virtually every built-in collection. Behind the scenes, foreach uses an enumerator (via GetEnumerator()) to walk through items one at a time. Any custom class can support foreach by implementing IEnumerable<T> itself.
Dictionary<TKey, TValue> stores data as key-value pairs, offering fast average-case lookup, insertion, and deletion by key, backed by a hash table. Keys must be unique - adding a value with an existing key throws an exception, while indexer assignment (dict[key] = value) overwrites it instead. Dictionary does not guarantee any particular iteration order.Queue<T> & Stack<T>
Queue<T> is a first-in-first-out (FIFO) collection - items are added with Enqueue() and removed with Dequeue(), just like a real-world line. Stack<T> is last-in-first-out (LIFO) - items are added with Push() and removed with Pop(), like a stack of plates. Both are useful for specific processing orders where a general-purpose List<T> would require extra bookkeeping.HashSet<T>
HashSet<T> is a collection that stores unique elements with no guaranteed ordering, backed by a hash table. Adding a duplicate element has no effect, since HashSet automatically enforces uniqueness. It provides very fast average-case performance for adding, removing, and checking membership, and offers built-in set operations like union, intersection, and difference.foreach & IEnumerable
foreach is C#'s dedicated loop for iterating over any collection that implements IEnumerable<T> - which includes arrays, List<T>, Dictionary<TKey,TValue>, and virtually every built-in collection. Behind the scenes, foreach uses an enumerator (via GetEnumerator()) to walk through items one at a time. Any custom class can support foreach by implementing IEnumerable<T> itself.