Why use the params keyword?
Why use the params keyword?
I know this is a basic question, but I couldn't find an answer.
Why use it? if you write a function or a method that's using it, when you remove it the code will still work perfectly, 100% as without it. E.g:
With params:
static public int addTwoEach(params int args)
{
int sum = 0;
foreach (var item in args)
sum += item + 2;
return sum;
}
Without params:
static public int addTwoEach(int args)
{
int sum = 0;
foreach (var item in args)
sum += item + 2;
return sum;
}
params key word means OPTIONAL parameters that can be passed or not to the Method. An array with out params key word means you MUST pass array argument to the method.
– Ailayna Entarria
May 5 '14 at 9:24
7 Answers
7
With params you can call your method like this:
params
addTwoEach(1, 2, 3, 4, 5);
Without params, you can’t.
params
Additionally, you can call the method with an array as a parameter in both cases:
addTwoEach(new int { 1, 2, 3, 4, 5 });
That is, params allows you to use a shortcut when calling the method.
params
Unrelated, you can drastically shorten your method:
public static int addTwoEach(params int args)
{
return args.Sum() + 2 * args.Length;
}
@Ken: You might need to import the
System.Linq namespace :)– Ranhiru Cooray
Sep 28 '11 at 8:31
System.Linq
Or return args.Sum(i => i + 2);
– bornfromanegg
Feb 19 '15 at 11:44
The sum with a delegate, though, does increase the complexity of the compiled code, which could potentially be less performant. Not really relevant in this particular situation, as it would not result in any closures, but it's worth knowing what the compiler's actually doing to make the best choice.
– Alexander Morou
Nov 28 '15 at 22:15
You could also use
return args.Select(x => x + 2).Sum();– bbvg
Aug 22 '17 at 21:07
return args.Select(x => x + 2).Sum();
Using params allows you to call the function with no arguments. Without params:
params
params
static public int addTwoEach(int args)
{
int sum = 0;
foreach (var item in args)
{
sum += item + 2;
}
return sum;
}
addtwoEach(); // throws an error
Compare with params:
params
static public int addTwoEach(params int args)
{
int sum = 0;
foreach (var item in args)
{
sum += item + 2;
}
return sum;
}
addtwoEach(); // returns 0
Generally, you can use params when the number of arguments can vary from 0 to infinity, and use an array when numbers of arguments vary from 1 to infinity.
Nice bit of additional information. Thanks
– richard
Oct 26 '13 at 18:50
actually an array can be empty.
new int[0]. hope this helps! :)– vidstige
Dec 21 '13 at 14:28
new int[0]
It allows you to add as many base type parameters in your call as you like.
addTwoEach(10, 2, 4, 6)
whereas with the second form you have to use an array as parameter
addTwoEach(new int {10,2,4,6})
short of 2 minutes and.. fame !
– Muds
Sep 3 '15 at 14:28
One danger with params Keyword is, if after Calls to the Method have been coded,
params
params
params
those Calls will continue to compile with one/more Expressions previously intended for required Parameters being treated as the optional params Parameter. I just ran into the worst possible case of this: the params Parameter was of Type object.
params
params
object
This is noteworthy because developers are used to the compiler slapping their wrists with the much, much more common scenario where Parameters are removed from a Method with all required Parameters (because the # of Parameters expected would change).
For me, it's not worth the shortcut. (Type) without params will work with 0 to infinity # of Parameters without needing Overrides. Worst case is you'll have to add a , new (Type) {} to Calls where it doesn't apply.
(Type)
params
, new (Type) {}
Btw, imho, the safest (and most readable practice) is to:
pass via Named Parameters (which we can now do even in C# ~2 decades after we could in VB ;P) (because:
1.1. it's the only way that guarantees prevention of unintended values passed to Parameters after Parameter order, Compatible-Type and/or count change after Calls have been coded,
1.2. it reduces those chances after a Parameter meaning change, because the likely new identifier name reflecting the new meaning is right next to the value being passed to it,
1.3. it avoids having to count commas and jump back & forth from Call to Signature to see what Expression is being passed for what Parameter, and
1.4. if you must use Optional Parameters (params or not), it allows you to search for Calls where a particular Optional Parameter is Passed (and therefore, most likely is not or at least has the possibility of being not the Default Value),
params
(NOTE: Reasons 1.2. and 1.3. can ease and reduce chances of error even on coding the initial Calls not to mention when Calls have to be read and/or changed.))
and
do so ONE - PARAMETER - PER - LINE for better readability (because:
2.1. it's less cluttered, and
2.2. it avoids having to scroll right & back left (and having to do so PER - LINE, since most mortals can't read the left part of multiple lines, scroll right and read the right part)).
NOTE:
Passing in Variables whose names mirror the Parameters' doesn't help when:
1.1. you're passing in Literal Constants (i.e. a simple 0/1 or true/false that even "'Best Practices'" may not require you use a Named Constant for and their purpose can't be easily inferred from the Method name),
1.2. the Method is significantly lower-level / more generic than the Caller such that you would not want / be able to name your Variables the same/similar to the Parameters (or vice versa), or
1.3. you're re-ordering / replacing Parameters in the Signature that may result in prior Calls still Compiling because the Types happen to still be compatible.
Having an auto-wrap feature like VS does only eliminates ONE (#2.2) of the 6 reasons I gave above. Prior to as late as VS 2015, it did NOT auto-indent (!?! Really, MS?!?) which increases severity of reason #2.1.
VS should have an option that generates Method Call snippets with Named Parameters (one per line of course ;P) and a compiler option that requires Named Parameters (similar in concept to Option Explicit in VB which, btw, the requirement of was prolly once thought equally as outrageous but now is prolly required by "'Best Practices'"). In fact, "back in my day" ;), in 1991 just months into my career, even before I was using (or had even seen) a language with Named Parameters, I had the anti-sheeple / "just cuz you can, don't mean you should" / don't blindly "cut the ends of the roast" sense enough to simulate it (using in-line comments) without having seen anyone do so. Not having to use Named Parameters (as well other syntax that save "'precious'" source code keystrokes) is a relic of the punch card era when most of these syntaxes started. There's no excuse for that with modern hardware and IDE's and much more complex software where readability is much, Much, MUCH more important. "Code is read much more often than is written". As long as you're not duplicating non-auto-updated code, every keystroke saved is likely to cost exponentially more when someone (even yourself) is trying to read it later.
I don't understand. Why can't you just enforce that there be at least one? Even without params there's nothing to stop you from passing
null or new object[0] as the argument.– Casey
Oct 28 '15 at 13:38
null
new object[0]
It's probably just too dangerous to ever have required parameters prior to the optional one (in case one or more of those required ones are removed after calls are coded). That may be why I've never seen required parameters before the the optional parameter in sample code in any docs on optional parameters. Btw, imho, the safest (and most readable practice) is to pass via named parameters (which we can now do even in C# ~2 decades after we could in VB). VS should have an option that generates method call snippets with named parameters (and do so 1 parameter per line).
– Tom
Mar 7 '17 at 2:41
I'm not really sure what you mean. The only way you can have required parameters and optional ones is to specify all the required ones first.
– Casey
Mar 8 '17 at 3:55
Ex. I declare
myMethod as void myMethod(int requiredInt, params int optionalInts). I / someone else codes one/more calls, i.e. myMethod(1), myMethod(1, 21), myMethod(1, 21, 22). I change myMethod to be void myMethod(params int optionalInts). All those calls will still compile with no errors even though their 1st parameters (the "1"'s) were clearly not intended to be passed as the 1st element of the optionalInts Parameter.– Tom
Mar 9 '17 at 5:11
myMethod
void myMethod(int requiredInt, params int optionalInts)
myMethod(1)
myMethod(1, 21)
myMethod(1, 21, 22)
myMethod
void myMethod(params int optionalInts)
optionalInts
Oh. Well, OK, in that particular case it may be ill-advised. I don't think there's any reason to avoid it if you need a string and 0-to-many ints or whatever.
– Casey
Mar 9 '17 at 17:52
No need to create overload methods, just use one single method with params as shown below
// Call params method with one to four integer constant parameters.
//
int sum0 = addTwoEach();
int sum1 = addTwoEach(1);
int sum2 = addTwoEach(1, 2);
int sum3 = addTwoEach(3, 3, 3);
int sum4 = addTwoEach(2, 2, 2, 2);
Thanks for your input but I don't think these kind of overloads would be a solution at all since with
params or without we would just pass a collection type to cover any count of collections.– MasterMastic
Apr 1 '14 at 6:54
params
You are right at some extent but what makes it cool is an overload with no input parameter eg int sum1 = addTwoEach();
– electricalbah
Apr 1 '14 at 9:20
params also allows you to call the method with a single argument.
params
private static int Foo(params int args) {
int retVal = 0;
Array.ForEach(args, (i) => retVal += i);
return retVal;
}
i.e. Foo(1); instead of Foo(new int { 1 });. Can be useful for shorthand in scenarios where you might need to pass in a single value rather than an entire array. It still is handled the same way in the method, but gives some candy for calling this way.
Foo(1);
Foo(new int { 1 });
Adding params keyword itself shows that you can pass multiple number of parameters while calling that method which is not possible without using it. To be more specific:
static public int addTwoEach(params int args)
{
int sum = 0;
foreach (var item in args)
{
sum += item + 2;
}
return sum;
}
When you will call above method you can call it by any of the following ways:
addTwoEach()
addTwoEach(1)
addTwoEach(new int{ 1, 2, 3, 4 })
But when you will remove params keyword only third way of the above given ways will work fine. For 1st and 2nd case you will get an error.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
The code of the method itself will still work perfectly... the calling code may well not...
– Jon Skeet
Sep 28 '11 at 8:30