The Power and Flexibility of the Params Keyword in C# 13

M.F.M Fazrin
3 min readMay 24, 2024

--

The params keyword in C# has always been a powerful tool, allowing developers to pass a variable number of arguments to a method. This feature can lead to concise and readable code, but it has traditionally been limited to working with arrays. However, with the advent of C# 13, the params keyword has become more versatile and performant.

The Params Paradox

In previous versions of C#, the params keyword could only be used with arrays. This meant that if a developer wanted to pass a list or an enumerable of integers to a method using the params keyword, it simply wouldn’t work. This limitation posed a significant constraint on the flexibility of the params keyword.

Real-World Example of Params Limitation

Consider a method that calculates the average of a series of numbers. With the params keyword, this method could be written as follows:

public double CalculateAverage(params int[] numbers)
{
return numbers.Average();
}

This method works well when you want to pass in a variable number of arguments directly:

double average = CalculateAverage(1, 2, 3, 4, 5);

However, if you have a List<int> or IEnumerable<int>, you would have to convert it to an array before passing it to the method:

numbers = new List {1, 2, 3, 4, 5}; double average = CalculateAverage(numbers.ToArray()); “>

List<int> numbers = new List<int> {1, 2, 3, 4, 5};
double average = CalculateAverage(numbers.ToArray());

This requirement to convert to an array is inconvenient and can lead to performance overhead.

C# 13 to the Rescue

C# 13 introduces a significant improvement to the params keyword by expanding its functionality to embrace a wider range of collection types. Now, developers can use params with enumerables like lists and even custom types.

Real-World Example of Params Enhancement

With the enhancement in C# 13, the CalculateAverage method can now accept a List<int> or IEnumerable<int> without needing to convert it to an array:

numbers) { return numbers.Average(); } List numbers = new List {1, 2, 3, 4, 5}; double average = CalculateAverage(numbers); “>

public double CalculateAverage(params IEnumerable<int> numbers)
{
return numbers.Average();
}
List<int> numbers = new List<int> {1, 2, 3, 4, 5};
double average = CalculateAverage(numbers);

This enhancement opens doors for improved code design and flexibility.

Performance Matters

While the flexibility of the params keyword is greatly improved in C# 13, it’s important to consider performance. Using params with different collection types can have varying performance implications.

For instance, using params with Span<T> or ReadOnlySpan<T> can lead to significant speed improvements. These types are stack-allocated, avoiding the overhead of boxing and heap allocation associated with reference types like arrays or lists.

Real-World Example of Params Performance

Consider a method that needs to process a large amount of data. Using params with Span<T> can lead to more efficient memory usage:

data) { // Process data… } int[] largeDataSet = GetLargeDataSet(); ProcessData(largeDataSet.AsSpan()); “>

public void ProcessData(params Span<int> data)
{
// Process data...
}
int[] largeDataSet = GetLargeDataSet();
ProcessData(largeDataSet.AsSpan());

In this example, AsSpan() creates a span over the array without copying the data, leading to efficient memory usage.

Embrace the Change

The improved params keyword in C# 13 is a welcome change. It empowers developers to write more flexible and potentially faster code. For optimal performance, consider using params with spans whenever possible.

This update is just one of the many ways C# 13 focuses on enhancing developer experience. As the language continues to evolve, developers can look forward to more exciting features in future iterations of C#. Stay tuned for more updates and keep coding!

--

--

M.F.M Fazrin

Senior Software Development Specialist @ Primary Health Care Corporation (Qatar)