Tuesday, March 3, 2026

C# 15: Collection Expression Arguments

In this post, let's have a look at a new C# 15 feature: Collection Expression Arguments which is now available with .NET 11 Preview 1.0.

With C# 12, we got Collection Expressions which gave us a nice unified syntax to initialize collections using [...]. But one thing we couldn't do was pass arguments to the underlying collection's constructor. For example, if you wanted to set a capacity for a List<T> or pass in a comparer for a HashSet<T>, you had to fall back to the traditional way.

Now with C# 15, we can use with(...) as the first element in a collection expression to pass arguments to the collection's constructor.

Let's have a look at some examples.

Note: C# 15 is supported on .NET 11. You will need the latest Visual Studio 2026 or the .NET 11 SDK. And make sure to set the LangVersion to preview.

Consider the below code.

string[] items = ["one", "two", "three"];

// Pass capacity
List<string> names = [with(capacity: items.Length * 2), .. items];

names.AddRange(["four", "five", "six", "seven"]);

foreach (string name in names)
{
    Console.WriteLine(name);
}
Here we are creating a List<string> using a collection expression and passing in a capacity hint to the constructor using with(capacity: items.Length * 2). The capacity here would be 6.

The output would be,
one
two
three
four
five
six
seven
Now you might notice, we are adding 7 items in total which exceeds the capacity of 6 we specified. And that's perfectly fine. Capacity is not a max size limit, it's a performance hint. It pre-allocates the internal array to that size upfront, so the list doesn't need to repeatedly resize as you add items. If you exceed it, the list simply grows automatically.

Now, let's have a look at another interesting example.

This is useful when you have a rough idea of how many items you'll have. Without it,
// Pass comparer
HashSet<string> set = [with(StringComparer.OrdinalIgnoreCase), "Hello", "HELLO", "hello"];

foreach (string name in set)
{ 
    Console.WriteLine(name); 
}
Here the output would be,
Hello
The set contains only one element because all three strings are equal when compared with OrdinalIgnoreCase. Previously, if you wanted to do this with collection expressions, you couldn't, you had to use the constructor directly. Now it's all nice and clean in a single expression.

Love it.

Read more:

Happy Coding.

Regards,
Jaliya

No comments:

Post a Comment