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.
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.
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.