Generic List
Explore the List<T> class in C# to understand its advantages over ArrayList, including strong typing and dynamic resizing. Learn to perform key operations such as adding, removing, sorting, and iterating elements safely and efficiently. This lesson also covers protecting internal data with IReadOnlyList<T>, helping you handle collections more securely and optimize memory management.
While the ArrayList class solved the fixed-size limitations of arrays, it introduced type safety problems. .NET developers addressed the concerns with a set of generic collection classes.
This lesson focuses on the List<T> class. Instead of using an object[] type array like the ArrayList class does, generic collections use parameter types. In the case of List<T>, the internal array is of type T[].
Generic collections introduce strong typing. The List<int> class can only store int items, and List<string> can only store string objects. We avoid the casting issues we had with the non-generic ArrayList collection.
Syntax
The List<T> class is instantiated just like any other class:
var listOfIntegers = new List<int>();
Here, we create a new instance of a generic list that can only store integers. The internal array is of type int[].
Note: In modern C#, we can initialize collections using collection expressions, such as List<int> listOfIntegers = [];. We will use this modern syntax in our upcoming examples.
Lists we create are initially empty. Empty means that the size of the internal array is zero. When we add the first item, though, a new array of size four is created.
listOfIntegers.Add(17);
Here, we use the Add method to append the integer 17 to the collection.
Each time this array fills, it doubles in size, and values from the previous array are copied over.
Understanding this resizing behavior helps optimize memory. If we know exactly how many items we plan to store, we can set the initial capacity of the list:
var listOfIntegers = new List<int>(500);
Here, we instantiate a list and explicitly set its starting capacity to 500 to avoid unnecessary memory reallocations. The List<int>(500) class initializes an int[] array of size 500.
Basic operations
Here are some of the most common operations we can perform with List<T>:
We can add an item to the end of the list using the ...