Skip to main content

C# Lists

Introduction

Lists are one of the most commonly used collection types in C#. Unlike arrays which have a fixed size, Lists are dynamic collections that can grow or shrink in size as needed. The List<T> class is part of the System.Collections.Generic namespace and represents a strongly-typed list of objects that can be accessed by index, much like an array.

Lists offer several advantages over arrays:

  • Dynamic sizing (grow and shrink as needed)
  • Rich set of methods for searching, sorting, and manipulating items
  • Type safety with generics
  • Efficient memory management

In this tutorial, we'll explore how to work with Lists in C#, from basic operations to more advanced techniques.

Getting Started with Lists

Creating a List

To use a List<T>, you first need to include the appropriate namespace:

using System;
using System.Collections.Generic;

Here are different ways to create a List:

// Creating an empty list of integers
List<int> numbers = new List<int>();

// Creating a list with capacity
List<string> names = new List<string>(10);

// Creating and initializing a list
List<string> fruits = new List<string> { "Apple", "Banana", "Orange" };

// Creating a list from an existing array
string[] colorArray = { "Red", "Green", "Blue" };
List<string> colors = new List<string>(colorArray);

Adding Elements to a List

You can add elements to a List using the Add method:

List<int> scores = new List<int>();
scores.Add(85);
scores.Add(92);
scores.Add(78);

// Output: Count = 3
Console.WriteLine($"Count = {scores.Count}");

To add multiple elements at once, use the AddRange method:

List<string> cities = new List<string> { "New York", "London" };
cities.AddRange(new string[] { "Paris", "Tokyo", "Sydney" });

// Output: New York, London, Paris, Tokyo, Sydney
Console.WriteLine(string.Join(", ", cities));

Basic List Operations

Accessing Elements

You can access elements in a List using index notation, similar to arrays:

List<string> planets = new List<string> { "Mercury", "Venus", "Earth", "Mars" };

// Accessing by index
string thirdPlanet = planets[2]; // "Earth"
Console.WriteLine($"Third planet: {thirdPlanet}");

// Modifying an element
planets[1] = "Venus - The Hot Planet";
Console.WriteLine($"Modified planet: {planets[1]}");

Removing Elements

Lists provide several methods to remove elements:

List<string> tools = new List<string> { "Hammer", "Screwdriver", "Wrench", "Pliers", "Saw" };

// Remove a specific element
tools.Remove("Wrench");

// Remove element at specific index
tools.RemoveAt(0); // Removes "Hammer"

// Remove a range of elements
tools.RemoveRange(1, 1); // Removes 1 element starting at index 1

// Output: Screwdriver, Saw
Console.WriteLine(string.Join(", ", tools));

Checking if an Element Exists

You can check if a List contains a specific element:

List<int> primeNumbers = new List<int> { 2, 3, 5, 7, 11, 13 };

bool containsSeven = primeNumbers.Contains(7); // true
bool containsNine = primeNumbers.Contains(9); // false

Console.WriteLine($"Contains 7: {containsSeven}");
Console.WriteLine($"Contains 9: {containsNine}");

Advanced List Operations

Finding Elements

Lists provide multiple methods for searching:

List<string> animals = new List<string> { "Lion", "Tiger", "Elephant", "Giraffe", "Zebra" };

// Find first element that matches a condition
string firstLongName = animals.Find(animal => animal.Length > 6); // "Elephant"
Console.WriteLine($"First animal with name longer than 6 characters: {firstLongName}");

// Find all elements that match a condition
List<string> shortNames = animals.FindAll(animal => animal.Length <= 5);
Console.WriteLine($"Animals with short names: {string.Join(", ", shortNames)}"); // "Lion, Tiger, Zebra"

// Find index of element
int tigerIndex = animals.IndexOf("Tiger"); // 1
Console.WriteLine($"Index of Tiger: {tigerIndex}");

Sorting Lists

Lists can be sorted using various methods:

List<int> numbers = new List<int> { 45, 12, 78, 23, 56 };

// Sort in ascending order
numbers.Sort();
Console.WriteLine($"Sorted numbers: {string.Join(", ", numbers)}"); // 12, 23, 45, 56, 78

// Sort in descending order
numbers.Reverse();
Console.WriteLine($"Reversed: {string.Join(", ", numbers)}"); // 78, 56, 45, 23, 12

// Custom sorting with a lambda expression
List<string> names = new List<string> { "Alice", "Bob", "Charlie", "David" };
names.Sort((x, y) => x.Length.CompareTo(y.Length)); // Sort by length
Console.WriteLine($"Sorted by length: {string.Join(", ", names)}"); // Bob, Alice, David, Charlie

Converting Between Lists and Arrays

You can easily convert between Lists and arrays:

// Array to List
int[] numberArray = { 1, 2, 3, 4, 5 };
List<int> numberList = new List<int>(numberArray);

// List to Array
string[] nameArray = numberList.ToArray();

Practical Examples

Example 1: Managing a To-Do List

Here's a simple application that manages a to-do list:

using System;
using System.Collections.Generic;

class TodoApp
{
static void Main()
{
List<string> todoList = new List<string>();

// Add some tasks
todoList.Add("Complete C# tutorial");
todoList.Add("Buy groceries");
todoList.Add("Call dentist");

// Display all tasks
DisplayTasks(todoList);

// Mark a task as completed (remove it)
Console.WriteLine("\nCompleting task: Buy groceries");
todoList.Remove("Buy groceries");

// Add another task
Console.WriteLine("Adding new task: Prepare presentation");
todoList.Add("Prepare presentation");

// Display updated list
DisplayTasks(todoList);
}

static void DisplayTasks(List<string> tasks)
{
Console.WriteLine("\n===== TO-DO LIST =====");
if (tasks.Count == 0)
{
Console.WriteLine("No tasks. Enjoy your day!");
return;
}

for (int i = 0; i < tasks.Count; i++)
{
Console.WriteLine($"{i + 1}. {tasks[i]}");
}
}
}

Output:

===== TO-DO LIST =====
1. Complete C# tutorial
2. Buy groceries
3. Call dentist

Completing task: Buy groceries
Adding new task: Prepare presentation

===== TO-DO LIST =====
1. Complete C# tutorial
2. Call dentist
3. Prepare presentation

Example 2: Managing Student Records

This example demonstrates a more complex application for managing student records:

using System;
using System.Collections.Generic;

class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public double GPA { get; set; }

public override string ToString()
{
return $"ID: {Id}, Name: {Name}, Age: {Age}, GPA: {GPA:F2}";
}
}

class StudentManager
{
static void Main()
{
// Create a list of students
List<Student> students = new List<Student>
{
new Student { Id = 1, Name = "Alice", Age = 22, GPA = 3.8 },
new Student { Id = 2, Name = "Bob", Age = 21, GPA = 3.2 },
new Student { Id = 3, Name = "Charlie", Age = 23, GPA = 3.5 },
new Student { Id = 4, Name = "Diana", Age = 20, GPA = 3.9 }
};

// Display all students
Console.WriteLine("All Students:");
DisplayStudents(students);

// Add a new student
Student newStudent = new Student { Id = 5, Name = "Eve", Age = 22, GPA = 3.7 };
students.Add(newStudent);
Console.WriteLine("\nAfter adding a new student:");
DisplayStudents(students);

// Find students with GPA > 3.5
List<Student> highPerformers = students.FindAll(s => s.GPA > 3.5);
Console.WriteLine("\nHigh performing students (GPA > 3.5):");
DisplayStudents(highPerformers);

// Sort students by GPA (descending)
students.Sort((s1, s2) => s2.GPA.CompareTo(s1.GPA));
Console.WriteLine("\nStudents sorted by GPA (highest first):");
DisplayStudents(students);
}

static void DisplayStudents(List<Student> studentList)
{
foreach (var student in studentList)
{
Console.WriteLine(student);
}
}
}

Output:

All Students:
ID: 1, Name: Alice, Age: 22, GPA: 3.80
ID: 2, Name: Bob, Age: 21, GPA: 3.20
ID: 3, Name: Charlie, Age: 23, GPA: 3.50
ID: 4, Name: Diana, Age: 20, GPA: 3.90

After adding a new student:
ID: 1, Name: Alice, Age: 22, GPA: 3.80
ID: 2, Name: Bob, Age: 21, GPA: 3.20
ID: 3, Name: Charlie, Age: 23, GPA: 3.50
ID: 4, Name: Diana, Age: 20, GPA: 3.90
ID: 5, Name: Eve, Age: 22, GPA: 3.70

High performing students (GPA > 3.5):
ID: 1, Name: Alice, Age: 22, GPA: 3.80
ID: 4, Name: Diana, Age: 20, GPA: 3.90
ID: 5, Name: Eve, Age: 22, GPA: 3.70

Students sorted by GPA (highest first):
ID: 4, Name: Diana, Age: 20, GPA: 3.90
ID: 1, Name: Alice, Age: 22, GPA: 3.80
ID: 5, Name: Eve, Age: 22, GPA: 3.70
ID: 3, Name: Charlie, Age: 23, GPA: 3.50
ID: 2, Name: Bob, Age: 21, GPA: 3.20

List Performance Considerations

When working with Lists, keep these performance considerations in mind:

  1. Initialization with Capacity: If you know the approximate size of your List in advance, initialize it with a capacity to avoid frequent resizing:
// Better performance for large lists
List<int> numbers = new List<int>(10000);
  1. Adding Elements: Adding elements to the end of a List is typically O(1), but can be O(n) if the List needs to resize.

  2. Inserting Elements: Inserting elements in the middle is O(n) because all subsequent elements need to be shifted.

  3. Searching: The Contains, IndexOf, and Find methods are O(n) operations as they need to potentially scan the entire List.

Summary

Lists are versatile collection types in C# that provide dynamic sizing and rich functionality for managing groups of related objects. They're ideal for situations where you need:

  • A collection that can grow or shrink
  • Frequent additions or removals
  • Easy access to elements by index
  • Rich manipulation methods like searching, sorting, and filtering

In this tutorial, we covered:

  • Creating Lists and adding elements
  • Basic operations like accessing, adding, and removing elements
  • Advanced operations like searching, sorting, and filtering
  • Converting between Lists and arrays
  • Practical examples showing Lists in real applications
  • Performance considerations

Lists are one of the most useful collection types in C#, and mastering them will significantly improve your ability to write efficient and effective C# code.

Exercises

  1. Create a program that reads a list of integers from the console, removes all duplicates, and prints the resulting list.

  2. Implement a simple contact manager that allows adding, removing, and searching for contacts in a list.

  3. Create a program that maintains a list of books. Allow the user to add books, display all books, search for a book by title, and sort books by author or publication year.

  4. Implement a shopping cart using a List of items. Allow adding items, removing items, calculating the total price, and applying discounts.

  5. Create a program that manages a playlist of songs, allowing the user to add songs, remove songs, shuffle the playlist, and play songs in order.

Additional Resources

💡 Found a typo or mistake? Click "Edit this page" to suggest a correction. Your feedback is greatly appreciated!