The first possible new feature of C# 13: Params collection
Only one month after the big release of .NET 8, the dotnet team is already working on the next iteration: .NET 9. With that also comes new language features. The first one is about to be merged into the main development branch: Params Collections.
What is a params collection?
Probably you came across the params
keyword in C# already. It allows you to pass a variable number of arguments to a method. For example:
void PrintNumbers(params int[] numbers)
{
foreach (var number in numbers)
{
Console.WriteLine(number);
}
}
Until now, the params
keyword was only allowed for arrays. But with the new feature, you can use it for any collection type. For example:
static void PrintNumbersUseSpan(params ReadOnlySpan<int> numbers)
{
foreach (var number in numbers)
{
Console.WriteLine(number);
}
}
static void PrintNumbersUseList(params List<int> numbers)
{
numbers.ForEach(Console.WriteLine);
}
Which can be called like this:
PrintNumbersUseSpan(1, 2, 3);
PrintNumbersUseList([1, 2, 3]);
This has the major advantage of having a nicer API surface for your methods and allows you to have a nicer API inside the method as well. For the sake of completeness, with C# 12 this isn't as bad as it was, as you can do this:
List<int> numbers = [1,2,3];
PrintNumbers([..numbers]);
static void PrintNumbers(params int[] array)
{
// ...
}
Still, I would argue it is more convenient to have the new version - it feels more coherent! You could also argue you get some performance "boost" when using types like ReadOnlySpan<int>
as there is no boxing required. That should be neglectable in almost all cases, as performance-critical code often doesn't use params
in the first place (at least until now).
Resources
If you want to know more about the feature:
- The proposal on GitHub: https://github.com/dotnet/csharplang/blob/main/proposals/params-collections.md
- You can play with that feature on SharpLab: Play around
Conclusion
A nice addition to the language even though you could consider it a minor one. While I was writing the article, the feature was not merged yet (but an open PR exists). So it is not 100% sure that it will make it into C# 13. But I am pretty certain it does!