In this article, we’ll learn about C# Lists, how to use them, and look at examples to make things clear. Lists are a type of collection in C#. They allow you to store multiple items (like numbers or words) in a single, organized way. If you’ve ever used an array, lists are similar but a lot more flexible!
What is a List?
A List in C# is like a container that holds multiple items of the same type. Unlike arrays, Lists can grow and shrink as you add or remove items. This means you don’t have to worry about the size of the list when you create it.
To use a List in C#, you need to include this line at the top of your code:
using System.Collections.Generic;
This tells C# that we want to use lists and other collection types.
Creating a List
To create a List, you need to define the type of items it will store. For example, if you want a List of integers (whole numbers), you write List<int>. If you want a List of strings (text), you write List<string>.
Here’s how you create an empty list:
List<int> numbers = new List<int>();
This creates a list called numbers that can hold integers. Right now, the list is empty, but we’ll add items next.
Adding Items to a List
To add an item to a List, you use the Add method. This method puts the item at the end of the list.
numbers.Add(10);
numbers.Add(20);
numbers.Add(30);
Now, the list numbers contains the values 10, 20, and 30.
Creating a List with pre-populated Items
Sometimes, you already know what items you need in a list, so you can make your code more readable and write fewer lines.
Here’s how you initialize a prepopulated List:
List<int> numbers = new List<int> {10, 20, 30};
Accessing Items in a List
You can access items in a List by using an index. The index represents the position of an item in the List, starting from 0.
Here’s an example:
int firstNumber = numbers[0]; // This will be 10
int secondNumber = numbers[1]; // This will be 20
If you try to access an index that doesn’t exist (like trying to get the 4th item in a list that only has 3 items), C# will throw an error.
Removing Items from a List
You can remove items from a List using the Remove method. Here’s how it works:
numbers.Remove(20); // Removes the value 20 from the list
Now, the list contains 10 and 30.
You can also remove an item at a specific index using RemoveAt:
numbers.RemoveAt(0); // Removes the item at index 0 (which is 10)
Now, the list only contains 30.
Checking the Size of a List
If you want to know how many items are in a List, you can use the Count property.
int count = numbers.Count;
In this example, count will be 1 because there’s only one item in the list (which is 30).
Looping Through a List
To go through each item in a List, you can use a foreach loop. This is great when you want to do something with every item in the list.
Here’s an example of printing each item:
List<string> names = new List<string> { "Alice", "Bob", "Charlie" };
foreach (string name in names)
{
Console.WriteLine(name);
}
This will print:
Alice
Bob
Charlie
List Example: Storing Grades
Let’s say we want to store a list of grades for a student. We can use a List to do this:
List<int> grades = new List<int> { 85, 90, 78, 92 };
grades.Add(88); // Adding a new grade
int gradeAtIndex3 = grades[3]; // Accessing the grade at index 3
grades.RemoveAt(2); // Removing the grade at index 2 (which is 78)
Now, the list grades will contain 85, 90, 92, 88. You can add more grades, remove them, or even loop through the list to calculate the average.
In C#, you can use a List to store any type of object, as long as you specify the type when you create the list. Lists are generic, which means they can work with different data types, from basic types like int and string to more complex types like custom classes.
Here are the types of objects you can use in a list:
1. Built-in Types
These are basic data types like integers, floats, characters, and booleans.
Integers: You can store whole numbers.
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
Strings: You can store text.
List<string> words = new List<string> { "apple", "banana", "cherry" };
Booleans: You can store true or false values.
List<bool> flags = new List<bool> { true, false, true };
2. Custom Types (Classes and Structs)
You can store objects of custom types, which you define using classes or structs.
For example, imagine you have a class called Person:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
You can create a list of Person objects:
List<Person> people = new List<Person>();
people.Add(new Person { Name = "Alice", Age = 30 });
people.Add(new Person { Name = "Bob", Age = 25 });
3. Collections (Other Lists or Arrays)
You can store other collections, like arrays or even lists themselves, inside a list. For example, you could have a list of lists or a list of arrays.
Nested lists: create, access, and loop through rows
List<List<int>> stores a list of integer lists. Each inner list can have a different number of items. The first index selects a row; the second selects an item within that row.
Run this complete console example:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<List<int>> rows = new List<List<int>>
{
new List<int> { 1, 2, 3 },
new List<int> { 4, 5 }
};
Console.WriteLine(rows[0][1]);
rows[1].Add(6);
rows.Add(new List<int>());
for (int row = 0; row < rows.Count; row++)
{
Console.WriteLine($"Row {row}: {string.Join(", ", rows[row])}");
}
}
}
2
Row 0: 1, 2, 3
Row 1: 4, 5, 6
Row 2:
rows[0][1] selects the second item of the first row. rows[1].Add(6) adds an item to the second row, while rows.Add(new List<int>()) creates an empty third row.
Check both indexes before accessing an item: the row index must be below rows.Count, and the item index must be below that row’s Count. Each index must also be nonnegative. An invalid index throws ArgumentOutOfRangeException. Empty rows are valid, but contain no item at index zero.
Create a separate inner list for each row, as above. Adding the same inner list twice shares one object, so changing it through one row also changes the other row. If every row must have the same fixed length, consider a rectangular array such as int[,].
List of Arrays:
List<int[]> listOfArrays = new List<int[]>();
listOfArrays.Add(new int[] { 1, 2, 3 });
listOfArrays.Add(new int[] { 4, 5, 6 });
4. Objects
If you’re not sure what type of object will be stored, you can create a List<object>. This allows you to store any type of object, but you’ll need to cast the items back to their original types when retrieving them.
List<object> mixedList = new List<object>();
mixedList.Add(42);
mixedList.Add("Hello");
mixedList.Add(new Person { Name = "Charlie", Age = 28 });
int number = (int)mixedList[0];
string text = (string)mixedList[1];
Person person = (Person)mixedList[2];
5. Enums
You can also store enum values in a List. For example:
enum Day { Monday, Tuesday, Wednesday, Thursday, Friday }
List<Day> days = new List<Day> { Day.Monday, Day.Friday };
Summary
In a C# List, you can store:
- Primitive types like
int,string,bool, etc. - Custom types like classes and structs.
- Other collections like lists or arrays.
- Any object by using
List<object>. - Enums.
Lists are highly versatile, and as long as you define the type, you can store nearly anything in them!
Conclusion
C# Lists are a powerful way to store collections of data that can grow and shrink as needed. They’re easy to use and much more flexible than arrays. You can add, remove, and access items by their index, and you can loop through the list to work with each item.
Whether you’re working with numbers, strings, or any other type, Lists are a great tool in C# programming.
References and more information
You can find a full list of functionality and methods available over at the List<T> class documentation at Microsoft Learn.