C# 13 params collections: small but useful
Posted: (EET/GMT+2)
The next version of the C# language, version 13, includes a small but useful improvement to params parameters.
Before C# 13, params was normally tied to arrays. For instance:
public static void LogMessages(params string[] messages)
{
foreach (string message in messages)
{
Console.WriteLine(message);
}
}
This feature allows a convenient call syntax:
LogMessages("Starting", "Connecting", "Done");
In C# 13, params is being extended to work with more collection types, not only arrays.
For example, a method can use ReadOnlySpan<T>:
public static void LogMessages(params ReadOnlySpan<string> messages)
{
foreach (string message in messages)
{
Console.WriteLine(message);
}
}
The call site remains simple:
LogMessages("Starting", "Connecting", "Done");
This is useful because ReadOnlySpan<T> can avoid some allocations in hot code paths.
The same idea also works with other collection-style parameter types supported by collection expressions. For example:
public static void PrintNumbers(params List<int> numbers)
{
foreach (int number in numbers)
{
Console.WriteLine(number);
}
}
And the call still looks natural:
PrintNumbers(1, 2, 3, 4);
Tip: do not immediately change existing APIs only because this syntax exists. For normal application code, params string[] is still simple and familiar.
Good candidates for the new syntax are:
- performance-sensitive helper methods
- APIs that already use spans
- library code where allocation behavior matters
- methods that work naturally with collection expressions.
For most business applications, this is not a feature you need every day. But it is a nice quality-of-life improvement when writing reusable libraries or low-allocation helper code.
Also, keeping mind that if the method is public API, think carefully before changing from params T[] to another collection type. The source code may look similar, but API compatibility and overload resolution still matter.
At this point, C# 13 is still preview, so test this in a separate branch before using it in shared production code.
Hope this helps!