Skip to content

Commit

Permalink
Edit pass to combine different concepts
Browse files Browse the repository at this point in the history
Combine errors on different concepts related to the `params` modifier.
  • Loading branch information
BillWagner committed May 22, 2024
1 parent 1c2f321 commit 14a9259
Showing 1 changed file with 57 additions and 236 deletions.
293 changes: 57 additions & 236 deletions docs/csharp/language-reference/compiler-messages/params-arrays.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,266 +50,87 @@ There are a few *errors* related to the `lock` statement and thread synchronizat
<!-- The text in this list generates issues for Acrolinx, because they don't use contractions.
That's by design. The text closely matches the text of the compiler error / warning for SEO purposes.
-->
- **CS0225**: *The params parameter must be a single-dimensional array or have a valid collection type*
- **CS0231**: *A params parameter must be the last parameter in a formal parameter list.*
- **CS0466**: *'method1' should not have a params parameter since 'method2' does not*
- **CS0674**: *Do not use `System.ParamArrayAttribute` or `System.ParamArrayAttribute`/`System.Runtime.CompilerServices.ParamCollectionAttribute`. Use the `params` keyword instead.*
- **CS0758**: *Both partial method declarations must use a `params` parameter or neither may use a `params` parameter*
- **CS1104**: *A parameter array cannot be used with `this` modifier on an extension method.*
- **CS1611**: *The params parameter cannot be declared as in `ref` or `out`*
- **CS1670**: *`params` is not valid in this context*
- **CS1751**: *Cannot specify a default value for a parameter array.*
- **CS9218**: *The type arguments for method cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly.*
- **CS9219**: *Ambiguity between expanded and normal forms of non-array params collection parameter of, the only corresponding argument has the type 'dynamic'. Consider casting the dynamic argument.*
- **CS9223**: *Creation of params collection results in an infinite chain of invocation of constructor.*
- **CS9224**: *Method cannot be less visible than the member with params collection.*
- **CS9225**: *Constructor leaves required member uninitialized.*
- **CS9227**: *Type does not contain a definition for a suitable instance `Add` method.*
- **CS9228**: *Non-array params collection type must have an applicable constructor that can be called with no arguments.*
- [**CS0225**](#parameter-and-argument-type-rules): *The params parameter must be a single-dimensional array or have a valid collection type*
- [**CS0231**](#method-declaration-rules): *A params parameter must be the last parameter in a formal parameter list.*
- [**CS0466**](#other-params-errors): *'method1' should not have a params parameter since 'method2' does not*
- [**CS0674**](#other-params-errors): *Do not use `System.ParamArrayAttribute` or `System.ParamArrayAttribute`/`System.Runtime.CompilerServices.ParamCollectionAttribute`. Use the `params` keyword instead.*
- [**CS0758**](#other-params-errors): *Both partial method declarations must use a `params` parameter or neither may use a `params` parameter*
- [**CS1104**](#method-declaration-rules): *A parameter array cannot be used with `this` modifier on an extension method.*
- [**CS1611**](#method-declaration-rules): *The params parameter cannot be declared as in `ref` or `out`*
- [**CS1670**](#method-declaration-rules): *`params` is not valid in this context*
- [**CS1751**](#method-declaration-rules): *Cannot specify a default value for a parameter array.*
- [**CS9218**](#parameter-and-argument-type-rules): *The type arguments for method cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly.*
- [**CS9219**](#parameter-and-argument-type-rules): *Ambiguity between expanded and normal forms of non-array params collection parameter of, the only corresponding argument has the type `dynamic`. Consider casting the dynamic argument.*
- [**CS9223**](#other-params-errors): *Creation of params collection results in an infinite chain of invocation of constructor.*
- [**CS9224**](#other-params-errors): *Method cannot be less visible than the member with params collection.*
- [**CS9225**](#other-params-errors): *Constructor leaves required member uninitialized.*
- [**CS9227**](#parameter-and-argument-type-rules): *Type does not contain a definition for a suitable instance `Add` method.*
- [**CS9228**](#parameter-and-argument-type-rules): *Non-array params collection type must have an applicable constructor that can be called with no arguments.*

In addition, the compiler might produce the following *warning* related to the `params` modifier on method parameters:

- **CS9220**: *One or more overloads of method having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch.*
- **CS9221**: *One or more indexer overloads having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch.*
- **CS9222**: *One or more constructor overloads having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch.*

## Compiler Error CS0225

The params parameter must be a single-dimensional array
The params parameter must have a valid collection type

When using the [params](../keywords/method-parameters.md#params-modifier) keyword, you must specify a single-dimensional array or collection of the data type. For more information, see [Methods](../../programming-guide/classes-and-structs/methods.md).

The following sample generates CS0225:

```csharp
// CS0225.cs
public class MyClass
{
public static void TestParams(params int a) // CS0225
// try the following line instead
// public static void TestParams(params int[] a)
{
}

public static void Main()
{
TestParams(1);
}
}
```

## Compiler Error CS0231

A params parameter must be the last parameter in a formal parameter list.

The [params](../keywords/method-parameters.md#params-modifier) parameter supports a variable number of arguments and must be after all other parameters. For more information, see [Methods](../../programming-guide/classes-and-structs/methods.md).

The following sample generates CS0231:

```csharp
// CS0231.cs
class Test
{
public void TestMethod(params int[] p, int i) {} // CS0231
// To resolve the error, use the following line instead:
// public void TestMethod(int i, params int[] p) {}
static void Main()
{
}
}
```

## Compiler Error CS0466

'method1' should not have a params parameter since 'method2' does not

You cannot use `params` parameter on a class member if the implemented interface doesn't use it.

The following sample generates CS0466.

```csharp
// CS0466.cs
interface I
{
void F1(params int[] a);
void F2(int[] a);
}

class C : I
{
void I.F1(params int[] a) {}
void I.F2(params int[] a) {} // CS0466
void I.F2(int[] a) {} // OK
public static void Main()
{
I i = (I) new C();

i.F1(new int[] {1, 2} );
i.F2(new int[] {1, 2} );
}
}
```

## Compiler Error CS0674

Do not use 'System.ParamArrayAttribute'. Use the 'params' keyword instead.
Do not use 'System.ParamArrayAttribute'/'System.Runtime.CompilerServices.ParamCollectionAttribute'. Use the 'params' keyword instead.
- [**CS9220**](#parameter-and-argument-type-rules): *One or more overloads of method having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch.*
- [**CS9221**](#parameter-and-argument-type-rules): *One or more indexer overloads having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch.*
- [**CS9222**](#parameter-and-argument-type-rules): *One or more constructor overloads having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch.*

The C# compiler does not allow for the use of <xref:System.ParamArrayAttribute?displayProperty=nameWithType>; use [params](../keywords/method-parameters.md#params-modifier) instead.
## Method declaration rules

The following sample generates CS0674:
The following errors indicate using a `params` modifier on a parameter when the `params` modifier isn't allowed in that context:

```csharp
// CS0674.cs
using System;
public class MyClass
{

public static void UseParams([ParamArray] int[] list) // CS0674
// try the following line instead
// public static void UseParams(params int[] list)
{
for ( int i = 0 ; i < list.Length ; i++ )
Console.WriteLine(list[i]);
Console.WriteLine();
}

public static void Main()
{
UseParams(1, 2, 3);
}
}
```

## Compiler Error CS0758

Both partial method declarations must use a params parameter or neither may use a params parameter

If one part of a partial method specifies a `params` parameter, the other part must specify one also.

Either add the `params` modifier in one part of the method, or remove it in the other.

The following code generates CS0758:

```csharp
using System;

public partial class C
{
partial void Part(int i, params char[] array);
partial void Part(int i, char[] array) // CS0758
{
}

public static int Main()
{
return 1;
}
}
```

## Compiler Error CS1104

A parameter array cannot be used with 'this' modifier on an extension method.

The first parameter of an extension method cannot be a params array.

Remember that the first parameter of an extension method definition specifies which type the method will "extend". It is not an input parameter. Therefore, it makes no sense to have a params array in this location. If you do have to pass in a params array, make it the second parameter.

The following example generates CS1104:

```csharp
// cs1104.cs
// Compile with: /target:library
public static class Extensions
{
public static void Test<T>(this params T[] tArr) {} // CS1104
}
```

## Compiler Error CS1611

The params parameter cannot be declared as in ref or out

The keywords [in](../keywords/method-parameters.md#in-parameter-modifier), [ref](../keywords/ref.md) or [out](../keywords/method-parameters.md#out-parameter-modifier) cannot be used with the [params](../keywords/method-parameters.md#params-modifier) keyword.

The following sample generates CS1611:

```csharp
// CS1611.cs
public class MyClass
{
public static void Test(params ref int[] a) // CS1611, remove ref
{
}

public static void Main()
{
Test(1);
}
}
```
- **CS0231**: *A params parameter must be the last parameter in a formal parameter list.*
- **CS1104**: *A parameter array cannot be used with `this` modifier on an extension method.*
- **CS1611**: *The params parameter cannot be declared as in `ref` or `out`*
- **CS1670**: *`params` is not valid in this context*
- **CS1751**: *Cannot specify a default value for a parameter array.*

## Compiler Error CS1670
The compiler enforces the following rules on your use of the `params` modifier on a method parameter:

params is not valid in this context
- The `params` modifier is allowed only on the last parameter in a formal parameter list. This includes any parameters with a default value.
- You can't include a default argument for the parameter when the `params` modifier is used.
- The `params` modifier can't be applied to reference parameter. A reference parameter is one with the `in`, `ref readonly`, `ref` or `out` modifier.
- The `params` modifier can't be combined with the `this` modifier on an extension method.
- The `params` modifier can't be used on an overloaded operator.

A number of C# features are incompatible with variable argument lists, and do not allow the `params` keyword, including the following:
In versions before C# 12, the `params` modifier can't be used on the parameter of an anonymous method or lambda expression.

- Parameter lists of anonymous methods
- Overloaded operators
## Parameter and argument type rules

The following sample generates CS1670:
The following errors indicate that the type of the parameter used with `params` is invalid:

```csharp
// CS1670.cs
public class C
{
public bool operator +(params int[] paramsList) // CS1670
{
return false;
}
- **CS9218**: *The type arguments for method cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly.*
- **CS9219**: *Ambiguity between expanded and normal forms of non-array params collection parameter of, the only corresponding argument has the type 'dynamic'. Consider casting the dynamic argument.*
- **CS0225**: *The params parameter must be a single-dimensional array or have a valid collection type*
- **CS9227**: *Type does not contain a definition for a suitable instance `Add` method.*
- **CS9228**: *Non-array params collection type must have an applicable constructor that can be called with no arguments.*

static void Main()
{
}
}
```
The following warnings indicate that the one of the possible overloads might involve dynamic dispatch. The dynamic nature of the argument doesn't participate in overload resolution.

## Compiler Error CS1751
- **CS9220**: *One or more overloads of method having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch.*
- **CS9221**: *One or more indexer overloads having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch.*
- **CS9222**: *One or more constructor overloads having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch.*

Cannot specify a default value for a parameter array.
In versions before C# 13, the `params` modifier is allowed on single-dimensional arrays only. No other types were valid.

The following sample generates CS1751:
Starting with C# 13 any valid collection type can be used. However, some restrictions remain. The collection type must follow the same rules as the target of a [collection expression](../operators/collection-expressions.md#conversions).

```csharp
// CS1751.cs
void Method(params object[] values = null)
{
}
```
## Other params errors

To fix the error:
The following errors indicate other issues with using the `params` modifier:

```csharp
// Explicitly passing null
object[] values = null;
Method(values);
- **CS0466**: *'method1' should not have a params parameter since 'method2' does not*
- **CS0674**: *Do not use `System.ParamArrayAttribute` or `System.Runtime.CompilerServices.ParamCollectionAttribute`. Use the `params` keyword instead.*
- **CS0758**: *Both partial method declarations must use a `params` parameter or neither may use a `params` parameter*
- **CS9223**: *Creation of params collection results in an infinite chain of invocation of constructor.*
- **CS9224**: *Method cannot be less visible than the member with params collection.*
- **CS9225**: *Constructor leaves required member uninitialized.*

void Method(params object[] values)
{
if (values == null)
{
A method that implements an interface must include the `params` modifier if and only if the interface member has the `params` modifier. Similarly, either both declarations of a `partial` method must include the `params` modifier, or none can include the `params` modifier.

}
}
```
You must use the `params` modifier. You can't apply the equivalent attributes, either <xref:System.ParamArrayAttribute?displayProperty=nameWithType> or <xref:System.Runtime.CompilerServices.ParamCollectionAttribute?displayProperty=nameWithType>.

## See also

- [Extension Methods](../../programming-guide/classes-and-structs/extension-methods.md)
- [Partial Classes and Methods](../../programming-guide/classes-and-structs/partial-classes-and-methods.md)
- [Collection expressions](../operators/collection-expressions.md)
- [params](../keywords/method-parameters.md#params-modifier)

0 comments on commit 14a9259

Please sign in to comment.