Back to: C# New Features Tutorials
Collection Expressions in C# with Examples
In this article, I will discuss Collection Expressions in C# with Examples. Please read our previous article discussing Primary Constructors for All Types in C# with Examples. C# 12 introduces Collection Expressions, a powerful feature that simplifies the initialization of collections such as arrays, lists, and spans. This feature allows a more concise and readable syntax for initializing collections, reducing the need for different initialization patterns.
What’s New in C# 12?
Before C# 12, initializing collections like arrays, lists, and spans required different syntax for each type, which could sometimes lead to inconsistency or confusion. With C# 12, Collection Expressions aim to provide a standard, readable, concise definition of collections.
What are Collection Expressions in C# 12?
Collection Expressions are a new feature introduced in C# 12 that simplifies the initialization of collections, such as arrays, lists, spans, and other types supporting collection initializers. This feature introduces a unified syntax for defining collections and easily supports the spread operator (..) to include elements from different collections.
Array Initialization:
You can initialize arrays using square brackets ([ ]), similar to how you would initialize lists and spans. Example: int[] numbers = [1, 2, 3, 4, 5];
List Initialization:
A list can now be initialized using the same syntax with square brackets. Example: List<int> list = [10, 20, 30, 40];
Span Initialization:
Spans are a type that represents contiguous regions of memory, and they can also be initialized with the same collection expression syntax. Example: Span<int> span = [5, 10, 15];
Combining Collections Using the Spread Operator (..):
The spread operator (..) allows you to combine elements from multiple collections into one.
int[] array1 = [1, 2, 3];
int[] array2 = [4, 5, 6];
int[] combined = [..array1, ..array2];
Example: Basic Use of Collection Expressions in C#
Let’s take a look at a basic example of how Collection Expressions can be used in C# 12.
namespace CSharp12NewFeatures { public class Program { static void Main() { // Using collection expressions for array initialization int[] numbers = [1, 2, 3, 4, 5]; Console.WriteLine("Array: " + string.Join(", ", numbers)); // Using collection expressions for List initialization List<string> colors = ["Red", "Green", "Blue"]; Console.WriteLine("List: " + string.Join(", ", colors)); // Using collection expressions for Span initialization Span<double> measurements = [1.5, 2.3, 3.7]; // string.Join() does not support Span<T> directly. // To use string.Join() with a Span<double>, we must first convert it to an array. Console.WriteLine("Span: " + string.Join(", ", measurements.ToArray())); // Combining multiple collections using the spread operator int[] array1 = [1, 2, 3]; int[] array2 = [4, 5, 6]; int[] combinedArray = [.. array1, .. array2]; Console.WriteLine("Combined Array: " + string.Join(", ", combinedArray)); } } }
Code Explanation:
- Array Initialization: The array numbers are initialized using the collection expression syntax [1, 2, 3, 4, 5], which is simpler and cleaner compared to the traditional new int[] { 1, 2, 3, 4, 5 }.
- List Initialization: The colors list is initialized in a similar manner with [“Red”, “Green”, “Blue”], replacing the need for new List<string> { “Red”, “Green”, “Blue” }.
- Span Initialization: The measurements span is initialized using the collection expression syntax [1.5, 2.3, 3.7].
- Combining Collections: The spread operator (..) is used to combine array1 and array2 into a new array combinedArray. The values from both arrays are combined into a single array.
Output:
Real-Time Use Case: Merging Multiple Data Sets using Collection Expressions in C#
Consider a scenario where you are dealing with an inventory management system in an e-commerce application and have multiple product data sources (e.g., WarehouseA and WarehouseB). You can use collection expressions to merge the product data from various sources efficiently.
namespace InventoryManagement { public class Program { static void Main() { // Simulate product data from two warehouses List<string> warehouseA = ["Laptop", "Smartphone", "Tablet"]; List<string> warehouseB = ["Headphones", "Monitor", "Mouse"]; // Merging the product data from both warehouses using collection expressions List<string> allProducts = [.. warehouseA, .. warehouseB]; // Displaying the combined product data Console.WriteLine("All Products: " + string.Join(", ", allProducts)); } } }
Code Explanation:
- The spread operator (..) is used to combine product data from warehouseA and warehouseB.
- The allProducts list combines both inventories into one list, which can then be processed or displayed.
Benefits of Collection Expressions:
- This simplifies the process of combining collections, especially when you need to merge multiple data sets.
- It reduces the need for looping through each collection and manually adding items.
- Collection expressions make the code cleaner and more readable.
Real-World Use Cases for Collection Expressions
- E-Commerce Inventory Merging: As shown in the example, collection expressions make the code much more concise and easier to maintain when merging product lists from multiple warehouses.
- Customer Data Aggregation: When aggregating customer data from multiple regions or databases, collection expressions can easily merge different data sources without complex logic.
- Combining Different Data Streams: In real-time data processing systems, where data from multiple sources needs to be combined (e.g., sensor data, web logs, etc.), collection expressions can simplify the merging of data into a unified stream for further processing.
- Flexible Collection Initialization: Whether you are working with arrays, lists, or spans, collection expressions allow for a unified approach to initializing these collections, reducing the need for different initialization patterns.
Real-Time Scenario: Task Management System
In this scenario, we have multiple team members working on different tasks for a project. Each team member has a list of assigned tasks, and we need to combine them into one unified list for project tracking. We will use Collection Expressions in C# 12 to simplify this process
using System; using System.Collections.Generic; namespace TaskManagementApp { // Task class to represent individual tasks public class Task { public string Title { get; } public string Assignee { get; } public DateTime DueDate { get; } public Task(string title, string assignee, DateTime dueDate) { Title = title; Assignee = assignee; DueDate = dueDate; } public override string ToString() { return $"Task: {Title}, Assigned to: {Assignee}, Due: {DueDate.ToShortDateString()}"; } } public class Program { static void Main() { // Simulate tasks from different team members List<Task> teamMember1Tasks = new List<Task> { new Task("Design Database Schema", "Alice", DateTime.Now.AddDays(3)), new Task("Create API Endpoints", "Alice", DateTime.Now.AddDays(5)) }; List<Task> teamMember2Tasks = new List<Task> { new Task("Implement Authentication", "Bob", DateTime.Now.AddDays(4)), new Task("Write Unit Tests", "Bob", DateTime.Now.AddDays(6)) }; List<Task> teamMember3Tasks = new List<Task> { new Task("Write Documentation", "Charlie", DateTime.Now.AddDays(2)), new Task("Review Pull Requests", "Charlie", DateTime.Now.AddDays(7)) }; // Using collection expressions to combine tasks from different team members List<Task> allTasks = [.. teamMember1Tasks, .. teamMember2Tasks, .. teamMember3Tasks]; // Display the combined list of tasks Console.WriteLine("All Tasks for the Project:"); foreach (var task in allTasks) { Console.WriteLine(task); } } } }
Code Explanation:
- Task Class: The Task class represents individual tasks that a team member is assigned. Each Task has a Title, Assignee, and DueDate.
- Simulating Tasks for Team Members: We simulate tasks for three team members: Alice, Bob, and Charlie. Each team member has their own list of tasks (teamMember1Tasks, teamMember2Tasks, and teamMember3Tasks).
- Using Collection Expressions: The spread operator (..) is used to combine the task lists from all three team members into a single list: allTasks. The syntax [..teamMember1Tasks, ..teamMember2Tasks, ..teamMember3Tasks] makes it easy to merge the collections into one without needing to manually loop through and add elements from each list.
- Displaying the Combined Tasks: After combining the tasks, we print the complete list of tasks for the project.
Output:
C# 12’s Collection Expressions feature significantly enhances the way we work with collections. By offering a unified syntax for initializing arrays, lists, spans, and more, along with the powerful spread operator (..), it makes the code simpler, more readable, and less error-prone. This feature not only improves code clarity but also boosts productivity by reducing repetitive code and providing a more natural way of combining collections.
In the next article, I will discuss the InlineArray Attribute in C# with Examples. In this article, I explain Collection Expressions in C# with Examples. I want your feedback. Please post your feedback, questions, or comments about this article.