Store, access, and organise data efficiently using built-in C# collections
Whether you’re managing a to-do list, user accounts, game scores, or form inputs โ how you store and access your data matters. C# offers a rich set of core data structures designed to help you write fast, reliable, and readable code.
This lesson introduces the most essential .NET collection types, how they work under the hood, and when to choose which one โ all with simple, practical examples.
๐งฑ Arrays โ Fixed-Size Foundations
Arrays in C# are the simplest way to hold a collection of items of the same type. Once created, their length cannot change.
string[] fruits = new string[3] { "Apple", "Banana", "Cherry" };
Console.WriteLine(fruits[1]); // Output: Banana
โ When to Use Arrays
- When you know the number of items in advance
- When memory efficiency is important
- When using index-based iteration
โ ๏ธ Limitations
- Cannot grow or shrink dynamically
- No methods like
AddorRemove
๐ List โ Flexible, Growable Collections
List<T> is a resizable array. It’s part of System.Collections.Generic and is the most commonly used data structure in modern C# projects.
List<string> tasks = new List<string>();
tasks.Add("Email client");
tasks.Add("Review report");
Console.WriteLine(tasks.Count); // Output: 2
๐ Useful Methods
Add(item)Remove(item)Insert(index, item)Contains(value)Sort()
โ When to Use
- General-purpose, ordered collection
- Need to dynamically add/remove items
- Maintaining insertion order matters
๐ Dictionary<TKey, TValue> โ Fast Key-Based Lookup
A dictionary stores unique keys paired with values. Ideal for situations where you need to search by label, not by position.
Dictionary<string, int> ages = new Dictionary<string, int>();
ages["Tom"] = 28;
ages["Emma"] = 34;
Console.WriteLine(ages["Emma"]); // Output: 34
โ Use Dictionary When
- You want fast retrieval using a key
- Each key is unique
- You’re mapping data (e.g., usernames โ scores)
โ ๏ธ Caution
- Always check
ContainsKey(key)before accessing - Keys are case-sensitive by default
๐ค Queue โ First In, First Out (FIFO)
A queue lets you process items in the order they arrived. Think of it like a line at a ticket counter.
Queue<string> printQueue = new Queue<string>();
printQueue.Enqueue("Doc1");
printQueue.Enqueue("Doc2");
Console.WriteLine(printQueue.Dequeue()); // Output: Doc1
โ When to Use
- You need first-in, first-out processing
- Task scheduling or messaging pipelines
๐ฅ Stack โ Last In, First Out (LIFO)
A stack lets you process the last item added first. Great for Undo functionality, parsing, and nested operations.
Stack<string> pages = new Stack<string>();
pages.Push("Home");
pages.Push("About");
Console.WriteLine(pages.Pop()); // Output: About
โ When to Use
- You need to reverse order
- Navigating back (e.g., browser tabs, app states)
๐งฎ HashSet โ Unique Items Only
A HashSet<T> stores only unique elements and ignores duplicates automatically.
HashSet<string> tags = new HashSet<string>();
tags.Add("tech");
tags.Add("ai");
tags.Add("tech"); // Duplicate ignored
Console.WriteLine(tags.Count); // Output: 2
โ When to Use
- You need to remove duplicates automatically
- Fast existence checks (
tags.Contains("ai")) - Unordered, no duplicates required
๐ LinkedList โ Custom Insertion with Node Control
A LinkedList<T> is a doubly-linked structure โ each node points to the next and previous node. This allows quick inserts and deletions anywhere in the list.
LinkedList<string> playlist = new LinkedList<string>();
playlist.AddLast("Intro");
playlist.AddLast("Track 1");
playlist.AddFirst("Welcome");
โ When to Use
- Insertions/deletions in the middle of a list
- Custom traversal and node control
- You donโt need index-based access
๐ง Summary Table
| Data Structure | Stores | Maintains Order | Key Lookup | Allows Duplicates | Resizable |
|---|---|---|---|---|---|
Array | Indexed data | โ๏ธ | โ | โ๏ธ | โ |
List<T> | Indexed data | โ๏ธ | โ | โ๏ธ | โ๏ธ |
Dictionary<K,V> | Key-value | โ | โ๏ธ | Keys โ | โ๏ธ |
Queue<T> | FIFO list | โ๏ธ | โ | โ๏ธ | โ๏ธ |
Stack<T> | LIFO list | โ๏ธ | โ | โ๏ธ | โ๏ธ |
HashSet<T> | Unique values | โ | โ | โ | โ๏ธ |
LinkedList<T> | Nodes | โ๏ธ | โ | โ๏ธ | โ๏ธ |
๐งช Challenge Task
Create a mini program that:
- Stores a list of registered usernames (
List<string>) - Prevents duplicates using a
HashSet<string> - Allows username lookup via
Dictionary<string, DateTime>(with registration date) - Displays all usernames in reverse order using a
Stack<string>
โ Best Practices
โ
Use List<T> as your default general-purpose container
โ
Use Dictionary<K,V> for quick lookup scenarios
โ
Avoid arrays unless you’re doing low-level operations
โ
Use Stack<T> and Queue<T> when order of operation matters
โ
Use HashSet<T> for enforcing uniqueness
โ
Keep memory usage in mind with large collections
๐ Want more?
Our live C# classes and Ocean Stack bootcamps cover practical collection use in real-world apps. Ask for course materials, challenges, or walkthroughs tailored to your level.