c# method with unlimited params or method with an array or list?
what's the difference between that and just creating a method that receives a list or an array?
The difference between
void M(params int[] x)
and
void N(int[] x)
is that M may be called like this:
M(1, 2, 3)
or like this:
M(new int[] { 1, 2, 3 });
but N may only be called in the second way, not the first way.
perhaps it has some impact in performance?
The impact to performance is that whether you call M
in the first way or the second way, either way you get an array created. Creating an array has a performance impact because it takes both time and memory. Remember that performance impacts should be measured against performance goals; it is unlikely that the cost of creating an extra array is the gating factor that is the difference between success and failure in the marketplace.
I don't fully understand or see in what way you would prefer the one with unlimited parameters.
It is purely and entirely a convenience for the author of the code which is calling the method; it is simply shorter and easier to write
M(1, 2, 3);
instead of writing
M(new int[] { 1, 2, 3 });
It just saves a few keystrokes on the caller's side. That is all.
A few questions you did not ask but perhaps would like to know the answer to:
What is this feature called?
Methods that allow a variable number of arguments to be passed on the caller side are called variadic. Params methods are how C# implements variadic methods.
How does overload resolution work with a variadic method?
When faced with an overload resolution problem, C# will consider both the "normal" and "expanded" forms, and the "normal" form always wins if both are applicable. For example, consider this:
void P(params object[] x){}
and we have a call
P(null);
There are two applicable possibilities. In "normal" form, we call P
and pass a null reference for the array. In "expanded" form, we call P(new object[] { null })
. In this case, normal form wins. If we had a call P(null, null)
then normal form is inapplicable and expanded form wins by default.
Challenge: Suppose we have var s = new[] { "hello" };
and a call P(s);
. Describe what happens at the call site and why. You might be surprised!
Challenge: Suppose we have both void P(object x){}
and void P(params object[] x){}
. What does P(null)
do, and why?
Challenge: Suppose we have both void M(string x){}
and void M(params string[] x){}
. What does M(null)
do, and why? How does this differ from the previous case?
Just did a little prototype. The answer appears to be that params
is simply syntactic sugar for passing in an array. That's not really a surprise. I created two versions of the same method, where the only difference is the "params" keyword. The IL generated for both was identical, except that a System.ParamArrayAttribute
was applied to the params
version.
Further, the IL generated at the call site was also the same between me calling the method with a manually declared new int[]
and calling the method just using the params
arguments.
So, the answer seems to be "convenience". There doesn't appear to be any difference in performance. You can also call a params
function with an array instead, so that's also not terribly surprising. It comes down to if it's easier for the consumer of your method to call it with any number of parameters (e.g. someMethod(1, 2, 3)
) than to always have to create a collection first (e.g. someMethod(new List<int>() { 1, 2, 3 } )
).
The feature of unlimited parameters offers the following benefits in many scenarios:
- Loose coupling
- Enhanced reusability
- Better overall performance of the application
Here is an example where the unlimited parameters option is a great choice
Consider that an application for sending emails needs to be built.
The function that sends the email must be able to handle either single or multiple values for the 'To', 'CC' and 'BCC' fields.
If the types of parameters are fixed to be arrays or lists for all fields (To, CC, BCC), then the calling function will be forced to deal with all the complexity of defining 3 arrays or lists in order to call the email sender function.
Even if the caller wants to send an email to just one address, the email sender function will force the caller to define and send 3 different arrays as parameters.
If the email sender function takes the unlimited params approach, then the caller function need not deal with all the complexity.
The unlimited parameters approach contributes to better runtime perfomance of the application by avoiding the creation of arrays or lists wherever unnecessary.