C# Collections Explained: List, Dictionary, HashSet and Queue

Collections are used in C# to store and manage groups of related values or objects. The .NET platform provides several collection types, each designed for different access, lookup, ordering, and storage requirements.

What are Collections in C#?

A collection is an object that contains multiple elements. Collections make it easier to add, remove, search, sort, and iterate over groups of data.

CSHARP
List<string> names = new List<string>
{
    "Alice",
    "Bob",
    "Charlie"
};

foreach (string name in names)
{
    Console.WriteLine(name);
}

List

List is one of the most commonly used collections in C#. It stores elements in an ordered sequence and provides convenient methods for adding, removing, searching, and accessing items by index.

CSHARP
List<int> numbers = new List<int>();

numbers.Add(10);
numbers.Add(20);
numbers.Add(30);

Console.WriteLine(numbers[0]);
numbers.Remove(20);

List Methods

  • Add adds an element
  • Remove removes a matching element
  • Contains checks whether an element exists
  • Count returns the number of elements
  • Sort orders the elements
  • Clear removes all elements

Dictionary

Dictionary stores data as key-value pairs. It is useful when you need to retrieve a value using a unique key.

CSHARP
Dictionary<int, string> users = new Dictionary<int, string>();

users[1] = "Alice";
users[2] = "Bob";
users[3] = "Charlie";

Console.WriteLine(users[2]);

Safely Accessing Dictionary Values

TryGetValue can be used when a key may not exist. It avoids throwing an exception for a missing key.

CSHARP
if (users.TryGetValue(2, out string? name))
{
    Console.WriteLine(name);
}
else
{
    Console.WriteLine("User not found");
}

HashSet

HashSet stores unique values. Adding a value that already exists does not create a duplicate entry.

CSHARP
HashSet<string> languages = new HashSet<string>();

languages.Add("C#");
languages.Add("Java");
languages.Add("C#");

Console.WriteLine(languages.Count);

Queue

Queue follows the first-in, first-out principle. The element added first is normally the first element removed.

CSHARP
Queue<string> queue = new Queue<string>();

queue.Enqueue("Task 1");
queue.Enqueue("Task 2");
queue.Enqueue("Task 3");

string firstTask = queue.Dequeue();
Console.WriteLine(firstTask);

Stack

Stack follows the last-in, first-out principle. The most recently added element is removed first.

CSHARP
Stack<string> pages = new Stack<string>();

pages.Push("Home");
pages.Push("Products");
pages.Push("Details");

string page = pages.Pop();
Console.WriteLine(page);

Collection Comparison

CollectionMain PurposeTypical Access
ListOrdered group of itemsIndex
DictionaryKey-value lookupKey
HashSetUnique valuesValue membership
QueueFIFO processingFront
StackLIFO processingTop

Choosing the Right Collection

The best collection depends on how your application accesses and modifies data.

  • Use List when you need an ordered collection and index-based access
  • Use Dictionary for fast key-based lookups
  • Use HashSet when duplicate values should not be stored
  • Use Queue for first-in, first-out processing
  • Use Stack for last-in, first-out processing

Iterating Through Collections

The foreach statement provides a simple way to process elements from most C# collections.

CSHARP
List<string> products = new List<string>
{
    "Laptop",
    "Phone",
    "Tablet"
};

foreach (string product in products)
{
    Console.WriteLine(product);
}

Using Collection Initializers

Collection initializers allow multiple values to be added when a collection is created.

CSHARP
List<int> scores = new List<int>
{
    80,
    90,
    75,
    95
};

Immutable Collections

Immutable collections provide collection types designed so that an existing collection cannot be changed after it is created. They can be useful when data should remain stable after construction.

CSHARP
using System.Collections.Immutable;

ImmutableList<int> numbers = ImmutableList.Create(10, 20, 30);

ImmutableList<int> updated = numbers.Add(40);

Common Collection Mistakes

  • Using a List when key-based lookup is required
  • Using Dictionary when duplicate keys are expected
  • Forgetting that HashSet removes duplicate values
  • Calling Dequeue or Pop on an empty collection
  • Choosing a collection without considering access patterns

Collection Best Practices

  • Choose collections based on the operations your application performs most
  • Use generic collections for compile-time type safety
  • Check collection state before removing elements when necessary
  • Use TryGetValue for safe dictionary lookups
  • Avoid unnecessary conversions between collection types
  • Use immutable collections when data should not be modified

Real-World Applications

  • Storing user records
  • Managing product catalogs
  • Caching values by key
  • Processing background jobs
  • Tracking unique identifiers
  • Implementing browser history
  • Managing application configuration

Practice Exercises

  • Create a List of student names
  • Build a Dictionary of product IDs and names
  • Remove duplicate values using HashSet
  • Create a Queue for customer requests
  • Build a Stack for page history
  • Compare two collections and identify their best use cases

Conclusion

C# provides a wide range of collection types for different programming needs. Understanding List, Dictionary, HashSet, Queue, and Stack helps developers choose the right data structure and write more efficient and maintainable applications.

Note: Note: Select a collection based on how data will be stored, searched, accessed, and modified rather than choosing one collection for every situation.