C# - Collections
C# - Modern Collections
Section titled “C# - Modern Collections”Collections are classes designed to store, manage, and manipulate groups of objects. C# provides a rich set of collection classes in the System.Collections.Generic namespace, which are essential for modern application development.
Generic vs. Non-Generic Collections
Section titled “Generic vs. Non-Generic Collections”Modern C# development exclusively uses generic collections (e.g., List<T>, Dictionary<TKey, TValue>). The <T> signifies a type parameter, allowing you to create collections that are strongly typed for a specific data type (like List<int> for integers or List<string> for strings).
Benefits of Generic Collections:
- Type Safety: The compiler enforces that only the correct type of item can be added, preventing runtime errors.
- Performance: They avoid the performance overhead of “boxing” and “unboxing” that occurs with non-generic collections when working with value types (like
intorstruct). - IntelliSense Support: Because the type is known, your code editor provides better autocompletion and error checking.
A Note on Legacy Collections: Older C# code might use non-generic collections from the System.Collections namespace, such as ArrayList and Hashtable. These are considered legacy and should not be used in new code due to their lack of type safety and lower performance.
Core Generic Collections
Section titled “Core Generic Collections”Here are the most commonly used generic collections:
1. List<T> - The Dynamic Array
Section titled “1. List<T> - The Dynamic Array”A List<T> is the modern, type-safe equivalent of ArrayList. It represents a strongly typed list of objects that can be accessed by index. Its size grows dynamically as you add elements.
using System;using System.Collections.Generic;
// Create a list of stringsvar fruits = new List<string> { "Apple", "Banana", "Cherry" };
// Add an elementfruits.Add("Date");
// Access by indexConsole.WriteLine($"The first fruit is: {fruits[0]}"); // Output: The first fruit is: Apple
// Iterate over the listforeach (var fruit in fruits){ Console.WriteLine(fruit);}2. Dictionary<TKey, TValue> - The Key-Value Store
Section titled “2. Dictionary<TKey, TValue> - The Key-Value Store”A Dictionary<TKey, TValue> stores key-value pairs, offering extremely fast lookups based on the key. It is the modern replacement for Hashtable.
using System;using System.Collections.Generic;
var userAges = new Dictionary<string, int>{ { "Alice", 30 }, { "Bob", 25 }};
// Add a new entryuserAges["Charlie"] = 35;
// Retrieve a value by keyif (userAges.TryGetValue("Alice", out int age)){ Console.WriteLine($"Alice's age is: {age}"); // Output: Alice's age is: 30}
// Check for existenceif (userAges.ContainsKey("David")){ Console.WriteLine("David exists.");} else { Console.WriteLine("David does not exist.");}3. HashSet<T> - The Set of Unique Items
Section titled “3. HashSet<T> - The Set of Unique Items”A HashSet<T> contains a collection of unique elements. It is highly optimized for checking if an item is present in the set.
using System;using System.Collections.Generic;
var uniqueTags = new HashSet<string> { "csharp", "dotnet", "programming" };
// Adding a duplicate item returns false and doesn't change the setbool added = uniqueTags.Add("csharp"); // returns falseConsole.WriteLine($"Added duplicate 'csharp': {added}");
// Fast containment checkif (uniqueTags.Contains("dotnet")){ Console.WriteLine("The set contains 'dotnet'.");}
// Output:// Added duplicate 'csharp': False// The set contains 'dotnet'.4. Queue<T> (FIFO) and Stack<T> (LIFO)
Section titled “4. Queue<T> (FIFO) and Stack<T> (LIFO)”A Queue<T> is a “First-In, First-Out” collection, like a line at a store. A Stack<T> is a “Last-In, First-Out” collection, like a stack of plates.
// Queue Example (FIFO)var taskQueue = new Queue<string>();taskQueue.Enqueue("Task 1");taskQueue.Enqueue("Task 2");Console.WriteLine(taskQueue.Dequeue()); // Output: Task 1
// Stack Example (LIFO)var browserHistory = new Stack<string>();browserHistory.Push("Page 1");browserHistory.Push("Page 2");Console.WriteLine(browserHistory.Pop()); // Output: Page 2Querying Collections with LINQ
Section titled “Querying Collections with LINQ”Language-Integrated Query (LINQ) provides powerful and readable syntax for filtering, sorting, and transforming data in any collection that implements IEnumerable<T>.
using System.Collections.Generic;using System.Linq;
var numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Use LINQ to find all even numbers greater than 5var results = numbers .Where(n => n % 2 == 0) // Filtering .Where(n => n > 5); // Chaining another filter
Console.WriteLine("Even numbers greater than 5:");foreach (var number in results){ Console.WriteLine(number);}
// Output:// Even numbers greater than 5:// 6// 8// 10