-
Notifications
You must be signed in to change notification settings - Fork 229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix S3878 FP: when a params argument is named #6893
Comments
Hello @afpirimoglu, |
Taking a look at the repro code for this 6893, I am afraid it is not actually reproducing what I have described in this ticket. Especially when there is another argument of the method that has an optional value defined, if the caller wants to rely on that optional value of that argument (i.e. not provide that in the call), then the caller has to reference the params argument by name. And if the caller is passing more than one item in the params argument, then the C# compiler requires the caller to pass the params argument as an array. Otherwise code does not compile! Expanding on the example code I had used in the description: public void MethodWithParams(
string stringParam = "abc", // Note that this is an optional parameter!!!!
params double[] doubleArgs)
{
// Does something
}
// Need to call MethodWithParams and want to use the default value of stringParam
// argument in the call, i.e. don't want to provide stringParam value in the call.
// Then I have to use name of the params doubleArgs in the call, as below calls do.
// This below call is fine, only one item in the params argument
MethodWithParams(doubleArgs: 0.2);
// This below commented line does not compile! Compiler gives error
// "CS8323 Named argument 'doubleArgs' is used out-of-position but is followed by an unnamed argument":
// MethodWithParams(doubleArgs: 0.2, 0.3);
// Neither this below commented line compiles, it gives the same CS8323 C# compiler error:
//MethodWithParams(0.2, 0.3);
// Only this below call compiles when the params arg being passed has more than one item in it,
// and there is an optional parameter in the method signature.
// But currently this below call gets Sonar warning S3878!
MethodWithParams(doubleArgs: new double[] { 0.2, 0.3 }); Hope above helps to demonstrate the issue better. And sometimes you want to specify the name of the argument in the call for better readibility, even if there was no other optional argument that compiler forces you to specify the name of the argument. A code example for it: public void MethodWithParams(
double weight, // Note this is not optional parameter
params double[] dimensions,
{
// Does something
}
// this call is ambiguous for the reader of the code:
MethodWithParams(0.4, 0.1, 0.2, 0.5)
// This below call is not ambiguous to the reader, since the parameter names are given.
// But this below call raises the S3878 warning! It should not have, because when the
// params argument is named in the call, and if there is more than one item in it,
// C# compiler forces that to be passed as an array!
MethodWithParams(weight: 0.4, dimensions: double[] {0.1, 0.2, 0.5});
// This does not compile!!
MethodWithParams(weight: 0.4, dimensions: 0.1, 0.2, 0.5); |
In summary, if the params argument was passed by name in the call and the params argument value contained more than one item in it, S3878 should not be applied to it; whether there was an optional argument in the method signature or not. Forgot to add: Thanks for looking into this! |
Hello @afpirimoglu, I'm a bit confused. Method(a: 1, argumentArray: new int[] { 1, 2 }); // Noncompliant FP Maybe the I confirm that we don't want to raise an issue when you pass an array/ initialize an array for params in the case of a named argument. |
`public class Repro6893
}` Changing the Method params argument as int[] will separate it from 6894. Something like this below, which I also added there that when the params argument has only one element in it, compiler allows that being passed without an array even if it is called by name. ` public void MethodInt(int a, params int[] argumentArray) { }
Also looking at the repro test code, I found out if the arguments are out of order, Sonar already is not raising issue on named params argument call, which is the last MethodInt call I made here. |
Description
S3878 should not be raised if the params argument is called by its name, which requires the value of it to be passed as an array. There are times params argument should be called by its name, as when there are other arguments with default values on them.
Repro steps
Expected behavior
S3878 should not be raised when the method is calling the params argument by its name.
Actual behavior
S3878 does not make distinction on whether the params argument was being called by name or not.
Known workarounds
None
The text was updated successfully, but these errors were encountered: