The .NET development platform takes pride in constantly improving its core programming language, C#. Despite being two decades old, it continues to evolve with every new release. The latest release, C#12, is no exception. In this article, we will explore a new feature called “Collection Expressions” introduced in the latest release – a new way of initializing arrays and collections. This feature offers a more concise syntax and helpful features like the “Spread” operator. So, let’s dive in and closely examine this new feature.

To download the source code for this article, you can visit our GitHub repository.

Let’s make a start.

What Are Collection Expressions?

Collection Expressions is a feature that lets us create and initialize a collection in a single line of code. It applies to any type that implements the IEnumerable interface and has an Add() method, including all the collection types in the System.Collections and System.Collections.Generic namespaces, such as List<T>, HashSet<T>, etc. Additionally, this feature applies to good old arrays as well. 

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

Now that we understand the collection expressions, it’s time to look at the previous syntax used until C#11.

The Old Syntax Before Collection Expressions

There are several ways to initialize arrays or collections in C# before the latest version. Let’s walk through them:

int[] oldSyntax1 = new int[] { 1, 2, 3, 4 };
int[] oldSyntax2 = new [] { 1, 2, 3, 4 };
int[] oldSyntax3 =  { 1, 2, 3, 4 };

Three syntax options are available to initialize an integer array in C#.

Firstly, oldSyntax1 uses explicit syntax wherein the type is specified, and a new instance of an array is explicitly created with values 1, 2, 3, and 4.

Secondly, oldSyntax2 utilizes the type inference feature of C# to infer the type of the array based on the provided values, allowing for the omission of the explicit type.

Lastly, oldSyntax3 employs the most concise syntax for array initialization in C#. It omits the explicit type and the keyword, relying solely on the provided values to initialize the array.

We will now explore the new syntax and the benefits it offers.

The New Syntax Using Collection Expressions

Let’s continue from our previous example of initializing an integer array, but this time with new syntax:

int[] array = [1, 2, 3, 4];

To initialize an array, the new syntax offers a more concise approach. Instead of using the new keyword or curly braces({}), we utilize square brackets([]) to enclose the values. It’s crucial to specify the target type explicitly, in this case, integer (int[]), since the var keyword is not compatible with this syntax. Hence, the new syntax streamlines the initialization process and provides better readability.

Furthermore, we can use the previously mentioned syntax for collections of List<T> types. Let’s witness it in action:

public static List<string> CreateListUsingNewExpressionSyntax()
{
    List<string> myList = ["John", "Paul", "George", "Ringo"];

    return myList;
}

To initialize myList of type List<string>, we use the new syntax. Furthermore, we can extend it to Span types:

public static Span<int> CreateSpanUsingNewExpressionSyntax()
{
     Span<int> span1 = [1, 2, 3, 4];

     return span1.ToArray();
}

We initialize the span1 using the new syntax and return it as an array.

Let’s now continue to use this syntax in declaring and initializing the two-dimensional (jagged) arrays:

public static int[][] CreateJaggedArray()
{
     int[] row0 = [1, 2, 3];
     int[] row1 = [4, 5, 6];
     int[] row2 = [7, 8, 9];
     int[][] vector = [row0, row1, row2];

     return vector;
}

To begin with, we initialize three integer arrays (row0, row1, row2) with different sets of values. After that, we declare an array of integer arrays (int[][] vector) and populate it with references to the previously created arrays. Finally, we return the jagged array (vector).

Additionally, we can use a feature called “Spread Operator” for this new syntax. Let’s understand it now.

Spread Operator Usage

This feature may already be familiar for developers coming from a Javascript/Typescript background as it works similarly. It involves spreading multiple arrays and their values into a new combined array. To achieve this, let’s see it in action through an example:

public static int[] CreateNewArrayUsingSpreadOperator(int[] array1, int[] array2, int[] array3)
{
    int[] combinedArray = [.. array1, .. array2, .. array3];

    return combinedArray;
}

To spread an array, we use the spread operator syntax (..) followed by the array name. We have used three arrays in this example, but we can use any number of arrays for the spread operator. We can even dynamically inject the additional items. Let’s extend the above example to showcase it:

public static int[] CreateNewArrayUsingSpreadOperatorWithAdditionalItems(int[] array1, int[] array2, 
     int[] array3)
{
     int[] combinedArray = [.. array1, 50, .. array2, .. array3];

     return combinedArray;
}

We are adding the element 50 after array1. This value of 50 will be included in the combinedArray. This is a very handy feature and can be helpful when manipulating multiple arrays or collections to process them further.

Conclusion

The Collection Expressions feature in C# 12 simplifies and improves how developers initialize collections in C# code. It streamlines the process of creating arrays and other collections with a more concise and readable syntax. This feature contributes to better code quality and a more positive developer experience.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!