Collection Interfaces in C#

Vaibhav • September 10, 2025

In C#, collections are central to organizing, storing, and managing groups of related objects. To provide consistency and interoperability across different collection types, C# defines a set of collection interfaces. Understanding these interfaces is crucial for writing flexible and maintainable code.

In this article, we will explore the key collection interfaces in C#, their purpose, and how they shape the behavior of common collection classes like List<T>, Dictionary<TKey, TValue>, and Queue<T>.

Understanding Collection Interfaces

Collection interfaces define a contract that a class must follow. They specify methods, properties, and behaviors without providing the implementation. This allows multiple collection classes to implement the same interface in ways that suit their performance and storage characteristics.

Using interfaces allows your code to remain flexible. For example, if a method accepts IEnumerable<T>, it can work with arrays, lists, or any custom collection that implements this interface.

Key Collection Interfaces

Here are some of the most commonly used collection interfaces in C#:

IEnumerable<T>

The IEnumerable<T> interface is the base interface for all generic collections. It provides a single method, GetEnumerator(), which allows iteration over the collection using foreach.


// Example: Using IEnumerable
IEnumerable numbers = new List { 1, 2, 3, 4 };
foreach (int number in numbers)
{
    Console.WriteLine(number);
}
    

ICollection<T>

The ICollection<T> interface extends IEnumerable<T> and adds methods for modifying the collection, such as Add(), Remove(), Contains(), and Clear(). It also provides the Count property.


// Example: Using ICollection
ICollection fruits = new List();
fruits.Add("Apple");
fruits.Add("Banana");
Console.WriteLine(fruits.Count); // Output: 2
    

IDictionary<TKey, TValue>

The IDictionary<TKey, TValue> interface represents collections of key/value pairs. Classes like Dictionary<TKey, TValue> implement this interface. It provides methods to add, remove, and lookup values using keys.


// Example: Using IDictionary
IDictionary users = new Dictionary();
users.Add(1, "Alice");
users.Add(2, "Bob");
Console.WriteLine(users[1]); // Output: Alice
    

IList<T>

The IList<T> interface extends ICollection<T> and represents an ordered collection of elements that can be accessed by index. Lists, arrays, and other indexed collections implement this interface.


// Example: Using IList
IList colors = new List { "Red", "Green", "Blue" };
colors[1] = "Yellow"; // Update element
Console.WriteLine(colors[1]); // Output: Yellow
    

ISet<T>

The ISet<T> interface represents a collection of unique elements. It provides set operations like UnionWith(), IntersectWith(), and ExceptWith().


// Example: Using ISet
ISet numbersSet = new HashSet { 1, 2, 3 };
numbersSet.Add(2); // Ignored since 2 already exists
Console.WriteLine(string.Join(", ", numbersSet)); // Output: 1, 2, 3
    

Choosing the Right Interface

Selecting the appropriate collection interface depends on your needs:

  • Use IEnumerable<T> for read-only iteration.
  • Use ICollection<T> for basic add/remove capabilities.
  • Use IList<T> when you need indexed access.
  • Use IDictionary<TKey, TValue> for key/value storage.
  • Use ISet<T> when uniqueness is required.
Tip: Favor programming to interfaces rather than concrete implementations. This allows your code to be more flexible, testable, and future-proof.

Summary

Collection interfaces provide a consistent foundation for working with different types of collections in C#. By understanding IEnumerable<T>, ICollection<T>, IList<T>, IDictionary<TKey, TValue>, and ISet<T>, you can write code that is flexible, maintainable, and ready to handle various data storage scenarios.

In the next article, we will explore how to initialize collections effectively and leverage their constructors for better code readability and performance.