Part 8: Collections in C#
Collections in C# provide powerful tools for managing and organising data efficiently. They enable developers to handle groups of objects with ease, whether you need fixed-size arrays or dynamic and flexible data structures like lists and dictionaries. In this article, we'll explore the primary types of collections in C#, their methods, and practical use cases.
1. Types of Collections in C#
1.1 Arrays
An array is a fixed-size collection of elements of the same type. It’s useful for scenarios where the number of items is known and does not change.
Example:
int[] numbers = {1, 2, 3, 4, 5}; foreach (int number in numbers) { Console.WriteLine(number); }
Key Methods and Properties:
Length
: Returns the number of elements.Array.Sort(array)
: Sorts the elements.Array.Reverse(array)
: Reverses the order of elements.
1.2 Lists
A List is a dynamic collection that can grow or shrink in size. Lists are part of the System.Collections.Generic
namespace and are more versatile than arrays.
Example:
List<string> names = new List<string> {"John", "Adrian", "Charlie"}; names.Add("Adrian"); foreach (string name in names) { Console.WriteLine(name); }
Key Methods:
Add(item)
: Adds an item to the list.Remove(item)
: Removes the first occurrence of an item.Contains(item)
: Checks if an item exists in the list.
1.3 Dictionaries
A Dictionary is a collection of key-value pairs, where each key is unique. Dictionaries are ideal for scenarios where quick lookups are needed.
Example:
Dictionary<int, string> students = new Dictionary<int, string> { {1, "Adrian"}, {2, "John"}, {3, "Charlie"} }; if (students.ContainsKey(2)) { Console.WriteLine($"Student ID 2: {students[2]}"); }
Key Methods:
Add(key, value)
: Adds a new key-value pair.Remove(key)
: Removes an item by key.ContainsKey(key)
: Checks if a specific key exists.
Performance Note: Dictionaries provide fast lookups due to their hashing mechanism, making them suitable for scenarios where keys are frequently searched.
1.4 Sets
A HashSet is a collection that contains unique elements and does not allow duplicates. It’s optimised for fast lookups.
Example:
HashSet<int> uniqueNumbers = new HashSet<int> {1, 2, 3, 3, 4}; foreach (int number in uniqueNumbers) { Console.WriteLine(number); }
Key Methods:
Add(item)
: Adds an item if it doesn’t already exist.Remove(item)
: Removes an item.Contains(item)
: Checks if an item exists.
Performance Note: Use HashSet
when you need to ensure uniqueness in your collection.
2. Methods of Collections and Their Uses
Common Methods Across Collections:
(LINQ will be discussed in the following articles)
- Iteration: Use
foreach
to iterate through items in a collection. - Sorting: Use
Sort()
in lists orOrderBy()
in LINQ for advanced sorting. - Filtering: LINQ methods like
Where()
allow filtering based on conditions. - Conversion: Convert between collections using
ToArray()
,ToList()
, etc.
Example of LINQ Filtering:
List<int> numbers = new List<int> {1, 2, 3, 4, 5}; var evenNumbers = numbers.Where(n => n % 2 == 0); foreach (int number in evenNumbers) { Console.WriteLine(number); }
3. Practical Example: Data Management with Collections
Scenario: Managing a Student Roster
This example demonstrates how to use multiple types of collections to manage student data.
Example:
using System; using System.Collections.Generic; class Program { static void Main() { // Store student data Dictionary<int, string> students = new Dictionary<int, string> { {1, "Adrian"}, {2, "John"}, {3, "Charlie"} }; // Add new students students.Add(4, "Diana"); // All students Console.WriteLine("Student Roster:"); foreach (var student in students) { Console.WriteLine($"ID: {student.Key}, Name: {student.Value}"); } // Check if a student exists if (students.ContainsKey(2)) { Console.WriteLine("Student ID 2 is in the roster."); } // Remove a student students.Remove(3); Console.WriteLine("Updated Roster:"); foreach (var student in students) { Console.WriteLine($"ID: {student.Key}, Name: {student.Value}"); } } } /* Student Roster: ID: 1, Name: Adrian ID: 2, Name: John ID: 3, Name: Charlie ID: 4, Name: Diana Student ID 2 is in the roster. Updated Roster: ID: 1, Name: Adrian ID: 2, Name: John ID: 4, Name: Diana */
4. Advanced Topics
Thread-Safe Collections
For applications requiring thread-safe operations, consider using ConcurrentDictionary
or other thread-safe collections from the System.Collections.Concurrent
namespace.
Example:
using System; using System.Collections.Concurrent; class Program { static void Main() { ConcurrentDictionary<int, string> safeDict = new ConcurrentDictionary<int, string>(); safeDict.TryAdd(1, "Adrian"); safeDict.TryAdd(2, "John"); foreach (var item in safeDict) { Console.WriteLine($"Key: {item.Key}, Value: {item.Value}"); } } }
Immutable Collections
To ensure the collection cannot be modified after creation, use immutable collections from System.Collections.Immutable
.
Example:
using System.Collections.Immutable; ImmutableList<string> immutableNames = ImmutableList.Create("Adrian", "John", "Charlie"); foreach (var name in immutableNames) { Console.WriteLine(name); }