C# Collections
Storing and managing groups of data efficiently
📦 What are Collections?
Collections are data structures that store groups of related objects. Unlike arrays, collections can grow and shrink dynamically, making them flexible for managing data in your applications.
// Simple List collection example
using System.Collections.Generic;
List<string> fruits = new List<string>();
fruits.Add("Apple");
fruits.Add("Banana");
Console.WriteLine(fruits[0]); // Apple
Output:
Apple
Common Collection Types
List<T>
Dynamic array with index access
List<int> numbers =
new List<int>();
Dictionary<K,V>
Key-value pairs for fast lookup
Dictionary<string, int>
ages = new();
HashSet<T>
Unique items, no duplicates
HashSet<string> unique =
new HashSet<string>();
Queue<T>
First-In-First-Out (FIFO)
Queue<string> line =
new Queue<string>();
🔹 List<T> - Dynamic Arrays
The List<T> collection in C# functions as a dynamic, type-safe array that automatically resizes. It provides methods like Add(), Remove(), Find(), and Sort(). Unlike arrays, Lists grow as needed, making them perfect for scenarios where the number of elements is unknown. They are the go-to choice for ordered, modifiable collections of objects.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Create a list of strings
List<string> cities = new List<string>();
// Add items
cities.Add("New York");
cities.Add("London");
cities.Add("Tokyo");
// Access by index
Console.WriteLine("First city: " + cities[0]);
// Count items
Console.WriteLine("Total cities: " + cities.Count);
// Loop through list
foreach (string city in cities)
{
Console.WriteLine("- " + city);
}
}
}
Output:
First city: New York
Total cities: 3
- New York
- London
- Tokyo
🔹 Dictionary<TKey, TValue> - Key-Value Pairs
A Dictionary<TKey, TValue> stores data as unique key-value pairs, enabling near-instant O(1) lookups by key. Each key must be unique, making it perfect for associations like ID-to-object mappings, configuration settings, or caching. It provides methods for adding, removing, and checking for keys. Dictionaries are fundamental for efficient data retrieval in applications like in-memory databases, lookup tables, or routing mechanisms, where fast access by a unique identifier is critical for performance.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Create a dictionary
Dictionary<string, int> ages = new Dictionary<string, int>();
// Add key-value pairs
ages["Alice"] = 25;
ages["Bob"] = 30;
ages["Charlie"] = 35;
// Access by key
Console.WriteLine("Alice's age: " + ages["Alice"]);
// Check if key exists
if (ages.ContainsKey("Bob"))
{
Console.WriteLine("Bob is in the dictionary");
}
// Loop through dictionary
foreach (var pair in ages)
{
Console.WriteLine(pair.Key + " is " + pair.Value + " years old");
}
}
}
Output:
Alice's age: 25
Bob is in the dictionary
Alice is 25 years old
Bob is 30 years old
Charlie is 35 years old
🔹 HashSet<T> - Unique Collections
HashSet<T> is a high-performance collection designed to store unique elements, automatically preventing duplicates. It uses hash-based lookups for fast membership tests (Contains), adds, and removals. This makes it ideal for scenarios requiring a distinct set of items, such as removing duplicates from a list, tracking visited nodes in a graph, or managing a collection of tags. HashSet<T> supports set operations like union, intersection, and difference, enabling powerful data comparisons and aggregations.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Create a HashSet
HashSet<string> colors = new HashSet<string>();
// Add items
colors.Add("Red");
colors.Add("Blue");
colors.Add("Red"); // Duplicate - won't be added
Console.WriteLine("Total unique colors: " + colors.Count);
// Check if item exists
if (colors.Contains("Blue"))
{
Console.WriteLine("Blue is in the set");
}
// Display all items
foreach (string color in colors)
{
Console.WriteLine("- " + color);
}
}
}
Output:
Total unique colors: 2
Blue is in the set
- Red
- Blue
🔹 Queue<T> and Stack<T>
Queue<T> and Stack<T> are specialized collections for processing items in specific orders. A Queue follows First-In-First-Out (FIFO), perfect for task scheduling, message buffering, or breadth-first search. A Stack follows Last-In-First-Out (LIFO), ideal for undo/redo functionality, parsing expressions, or depth-first search. Both provide efficient enqueue/dequeue and push/pop operations, making them essential for algorithms and scenarios where order of processing is a fundamental requirement.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Queue - FIFO
Queue<string> line = new Queue<string>();
line.Enqueue("First person");
line.Enqueue("Second person");
line.Enqueue("Third person");
Console.WriteLine("Queue (FIFO):");
Console.WriteLine("Serving: " + line.Dequeue()); // First person
// Stack - LIFO
Stack<string> plates = new Stack<string>();
plates.Push("Plate 1");
plates.Push("Plate 2");
plates.Push("Plate 3");
Console.WriteLine("\nStack (LIFO):");
Console.WriteLine("Taking: " + plates.Pop()); // Plate 3
}
}
Output:
Queue (FIFO):
Serving: First person
Stack (LIFO):
Taking: Plate 3
🔹 Collection Initialization
C# provides a concise syntax for initializing collections inline, improving code readability and reducing verbosity. Using curly braces, you can populate List<T>, Dictionary<TKey, TValue>, and other collections at the point of creation. For example: new List<int> { 1, 2, 3 } or new Dictionary<string, int> { {"A", 1} }. This feature saves multiple Add calls, makes intent clearer, and is widely used in setting up test data, configuration, or default collections.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// List initialization
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// Dictionary initialization
Dictionary<string, string> capitals = new Dictionary<string, string>
{
{ "USA", "Washington DC" },
{ "France", "Paris" },
{ "Japan", "Tokyo" }
};
// Display
Console.WriteLine("Numbers: " + string.Join(", ", numbers));
Console.WriteLine("Capital of France: " + capitals["France"]);
}
}
Output:
Numbers: 1, 2, 3, 4, 5
Capital of France: Paris