Understanding IEnumerable, ICollection, IList, and List

In .NET, collections are very important for handling and working with groups of objects. C# provides different interfaces and classes like IEnumerable, ICollection, IList, and List. Each of these has its own use and features. Thus, knowing the difference between them is important for writing better programs.

List

1. IEnumerable

The IEnumerable interface is the most basic of the collection interfaces. It enables iteration over a collection of a specified type using a foreach loop.

Key Points

  • It is defined in the System. Collections namespace.
  • Provides one method: GetEnumerator.
  • Read-only: You cannot add, remove, or modify items.
  • Suitable for forward-only iteration.

Example

using System;
using System.Collections.Generic;
class Program
{
    static void Main()
    {
        IEnumerable<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
        int index = 0;

        foreach (var num in numbers)
        {
            Console.WriteLine($"Element at index {index}: {num}"); // Outputs: 1 2 3 4 5
            index++;
        }
    }
}

Output

Element

2. ICollection

ICollection builds upon IEnumerable by adding methods for modifying the collection, such as adding or removing items.

Key Points

  • Defined in the System.Collections.Generic namespace.
  • Provides methods like Add, Remove, and Clear.
  • Includes properties like Count to get the number of elements.

Example

using System;
using System.Collections.Generic;
class Program
{
    static void Main()
    {
        ICollection<string> fruits = new List<string> { "Apple", "Banana" };
        fruits.Add("Cherry");
        fruits.Remove("Banana");
        foreach (var fruit in fruits)
        {
            Console.WriteLine(fruit); // Outputs: Apple Cherry
        }
        Console.WriteLine($"Total fruits: {fruits.Count}"); // Outputs: 2
    }
}

Output

Apple

3. IList

IList extends ICollection by adding support for accessing elements by index, making it ideal for scenarios requiring random access.

Key Points

  • Defined in the System.Collections.Generic namespace.
  • Allows indexed access (list[0]).
  • Supports inserting and removing items at specific indices.

Example

using System;
using System.Collections.Generic;
class Program
{
    static void Main()
    {
        IList<int> numbers = new List<int> { 10, 20, 30 };

        // Display initial list
        Console.WriteLine("Initial list: " + string.Join(", ", numbers));

        // Update value at index 1
        numbers[1] = 25;
        Console.WriteLine("Updated index 1 to 25: " + string.Join(", ", numbers));

        // Insert 35 at index 2
        numbers.Insert(2, 35);
        Console.WriteLine("Inserted 35 at index 2: " + string.Join(", ", numbers));

        // Remove the first element (index 0)
        numbers.RemoveAt(0);
        Console.WriteLine("Removed element at index 0: " + string.Join(", ", numbers));

        // Display final list with indexes
        Console.WriteLine("\nFinal list with indexes:");
        for (int i = 0; i < numbers.Count; i++)
        {
            Console.WriteLine($"Index {i}: {numbers[i]}");
        }
    }
}

Output

Initial list

4. List

The list is a concrete implementation of IList. It provides additional methods and properties for dynamic arrays.

Key Points

  • Defined in the System.Collections.Generic namespace.
  • Dynamically resizable array.
  • Offers methods like Find, Sort, Reverse, and BinarySearch.

Example

using System;
using System.Collections.Generic;
class Program
{
    static void Main()
    {
        List<string> cities = new List<string> { "New York", "London", "Tokyo" };

        // Display initial list
        Console.WriteLine("Initial list of cities: " + string.Join(", ", cities));

        // Add a new city
        cities.Add("Paris");
        Console.WriteLine("Added 'Paris' to the list: " + string.Join(", ", cities));

        // Sort the list alphabetically
        cities.Sort();
        Console.WriteLine("Sorted list alphabetically: " + string.Join(", ", cities));

        // Display final list with indexes
        Console.WriteLine("\nFinal sorted list with indexes:");
        for (int i = 0; i < cities.Count; i++)
        {
            Console.WriteLine($"Index {i}: {cities[i]}");
        }

        // Get the index of "Tokyo"
        int tokyoIndex = cities.IndexOf("Tokyo");
        Console.WriteLine($"\nIndex of 'Tokyo': {tokyoIndex}");
    }
}

Output

Output

Key Differences
 

Feature IEnumerable ICollection IList List
Namespace System.Collections System.Collections.Generic System.Collections.Generic System.Collections.Generic
Read/Write Read-only Read/Write Read/Write Read/Write
Index-based Access No No Yes Yes
Supports Add/Remove No Yes Yes Yes
Dynamic Sizing N/A N/A N/A Yes
Additional Features Minimal Basic Indexed Access Advanced Operations


When to Use What?

  • IEnumerable: Use when you need simple iteration without modifying the collection.
  • ICollection: Use when you need to add or remove items but do not require indexed access.
  • IList: Use when you need indexed access to elements and modification operations.
  • List: Use when you need a full-featured, dynamic collection with advanced methods.

Conclusion

Understanding the differences between IEnumerable, ICollection, IList, and List helps you choose the right tool for your specific needs. By choosing the right type, you can write code that is more efficient, maintainable, and easier to understand.

Up Next
    Ebook Download
    View all
    Learn
    View all