-
Notifications
You must be signed in to change notification settings - Fork 222
/
ArrayPassedAsParams.cs
130 lines (106 loc) · 5.43 KB
/
ArrayPassedAsParams.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using System;
public class Program
{
public void Base(string[] myArray)
{
Method(new string[] { "s1", "s2" }); // Noncompliant {{Remove this array creation and simply pass the elements.}}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Method(new string[] { "s1" }); // Noncompliant
Method(new[] { "s1" }); // Noncompliant
Method(new string[] { }); // Noncompliant
Method("s1"); // Compliant
Method("s1", "s2"); // Compliant
Method(myArray); // Compliant
Method(new string[12]); // Compliant
Method2(1, new string[] { "s1", "s2" }); // Noncompliant {{Remove this array creation and simply pass the elements.}}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Method2(1, new string[] { "s1" }); // Noncompliant
Method2(1, "s1"); // Compliant
Method2(1, "s1", "s2"); // Compliant
Method2(1, myArray); // Compliant
Method2(1, new string[12]); // Compliant
Method3(new string[] { "s1", "s2" }); // Compliant
Method3(new string[] { "s1", "s2" }, "s1"); // Compliant
Method3(new string[] { "s1", "s2" }, new string[12]); // Compliant
Method3(new string[] { "s1", "s2" }, new string[] { "s1", "s2" }); // Noncompliant
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Method3(null, null); // Compliant
Method4(new [] { "s1" }); // Compliant
Method4(new [] { "s1", "s2" }); // Compliant
Method3(args: new string[] { "s1", "s2" }, a: new string[12]); // Compliant (if you specifically require the arguments to be passed in this order there is no way of making this compliant, thus we shouldn't raise)
Method3(args: new string[12], a: new string[] { "s1", "s2" }); // Compliant
var s = new MyClass(1, new int[] { 2, 3 }); // Noncompliant
// ^^^^^^^^^^^^^^^^^^
var s1 = new MyClass(1, 2, 3); // Compliant
s1 = new MyClass(args: new int[] { 2, 3 }, a: 1); // Compliant (if you specifically require the arguments to be passed in this order there is no way of making this compliant, thus we shouldn't raise)
var s2 = new MyOtherClass(args: new int[12], a: new int[] { 2, 3 }); // Compliant
var s3 = new IndexerClass();
var indexer1 = s3[new int[] { 1, 2 }]; // FN
var indexer2 = s3?[new int[] { 1, 2 }]; // FN
var indexer3 = s3[1, 2]; // Compliant
}
public void Method(params string[] args) { }
public void Method2(int a, params string[] args) { }
public void Method3(string[] a, params string[] args) { }
public void Method4(object[] a, params object[] args) { }
public void Method5(params string[] a, params string[] args) { } // Error [CS0231]
}
public class MyClass
{
public MyClass(int a, params int[] args) { }
}
public class MyOtherClass
{
public MyOtherClass(int[] a, params int[] args) { }
}
public class IndexerClass
{
public int this[params int[] i] => 1;
}
public class Repro6894
{
//Reproducer for https://github.com/SonarSource/sonar-dotnet/issues/6894
public void Method(params object[] args) { }
public void MethodArray(params Array[] args) { }
public void MethodJuggedArray(params int[][] args) { }
public void CallMethod()
{
Method(new String[] { "1", "2" }); // Noncompliant, TP. Elements in args: ["1", "2"]
// The argument given for a parameter array can be a single expression that is implicitly convertible (§10.2) to the parameter array type.
// In this case, the parameter array acts precisely like a value parameter.
// see: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#14625-parameter-arrays
Method(new object[] { new int[] { 1, 2} }); // Noncompliant. TP Elements in args: [System.Int32[]]
Method(new int[] { 1, 2, 3, }); // Noncompliant, FP. Elements in args: [System.Int32[]]
Method(new String[] { "1", "2" }, new String[] { "1", "2"}); // Noncompliant, FP. Elements in args: [System.String[], System.String[]]
// ^^^^^^^^^^^^^^^^^^^^^^^^
Method(new String[] { "1", "2"}, new int[] { 1, 2}); // Noncompliant, FP. Elements in args: pSystem.String[], System.Int32[]]
// ^^^^^^^^^^^^^^^^^
MethodArray(new String[] { "1", "2" }, new String[] { "1", "2" }); // Noncompliant, FP. Elements in args: [System.String[], System.String[]]
MethodArray(new int[] { 1, 2 }, new int[] { 1, 2 }); // Noncompliant, FP. Elements in args: [System.Int32[], System.Int32[]]
MethodJuggedArray(new int[] { 1, 2 }); // Noncompliant, FP. Elements in args: [System.Object[]]
}
}
// Reproducer for https://github.com/SonarSource/sonar-dotnet/issues/6893
public class Repro6893
{
public void Method(int a, params object[] argumentArray) { }
public void CallMethod()
{
Method(a: 1, argumentArray: new int[] { 1, 2 }); // Noncompliant FP
}
}
// Reproducer for https://github.com/SonarSource/sonar-dotnet/issues/6977
public class Repro6977
{
class ParamsAttribute : Attribute
{
public ParamsAttribute(params string[] values) { }
}
internal enum Foo
{
[Params(new[] { "1", "2" })] // FN
Bar,
[Params("1", "2")]
FooBar
}
}