Benefits of collection expressions

October 20th 2023 C#

Collection expressions are a new feature of C# 12. At first glance, it's very similar to collection initializers, and you might wonder what benefits it brings except for the slightly different syntax. Let's take a closer look.

Since long before C# 12, you can use a collection initializer to create an array with some items in it:

var oldSyntax = new[] { 1, 2, 3 };

In C# 12, you can achieve the same using the new collection expressions syntax:

int[] newSyntax = [1, 2, 3];

Since the new syntax doesn't allow you to specify the type of the collection, you can't use it with explicitly typed local variables. Instead, you have to explicitly declare the variable type so that the compiler can create an instance of it based on the new collection expression syntax.

In this scenario, the old and the new syntax are almost equivalent. In some other cases, you might spare a few more keystrokes when using the new syntax. For example, when creating a jagged array. This is how you would do it using collection initializers:

var oldSyntax = new[]
    new[] { 1, 2 },
    new[] { 3, 4 },
    new[] { 5, 6 },

And this is how you can do it with collection expressions:

int[][] newSyntax = [[1, 2], [3, 4], [5, 6]];

The simpler collection expressions syntax in this case is acknowledged even by Visual Studio. If you use a collection initializer instead of a collection expression, it will suggest a refactor:

Refactor for collection initialization in Visual Studio

Although the new syntax can be shorter than the old one in some scenarios, that's hopefully not a good enough reason for a new language feature. However, there are other benefits to the new syntax.

Collection initializers don't work with Span types:

var oldSyntax = new Span<int> { 1, 2, 3 };

The above code will fail with a compiler error:

Cannot initialize type Span<int> with a collection initializer because it does not implement System.Collections.IEnumerable.

However, you can use the new collection expression syntax:

Span<int> newSyntax = [1, 2, 3];

The new syntax also introduces the spread element, akin to the JavaScript spread syntax:

int[] array = [1, 2];
Span<int> span = [3, 4];
List<int> list = [5, 6];
int[] finalArray = [.. array, .. span, .. list];

You can use it to flatten items from multiple collections into a new collection instead of calling AddRange, for example.

You can find a small sample project with all the cases from this post ready to run in my GitHub repository.

All in all, collection expressions still don't add that much to the language, but you might just as well be aware of the new syntax since it's available. In some cases, it can actually simplify your code to some extent and make it more readable.

Get notified when a new blog post is published (usually every Friday):

If you're looking for online one-on-one mentorship on a related topic, you can find me on Codementor.
If you need a team of experienced software engineers to help you with a project, contact us at Razum.
Creative Commons License