Skip to content

Commit

Permalink
Add errors and warnings for params arrays (#41027)
Browse files Browse the repository at this point in the history
* Move all params articles into one article

Consolidate all related (existing) content into one article. Add new errors and warnings to the introduction.

* fix warning

* Edit pass to combine different concepts

Combine errors on different concepts related to the `params` modifier.

* Add final new errors.
  • Loading branch information
BillWagner authored May 28, 2024
1 parent b83a83e commit 3b1a1b6
Show file tree
Hide file tree
Showing 14 changed files with 188 additions and 362 deletions.
36 changes: 36 additions & 0 deletions .openpublishing.redirection.csharp.json
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,10 @@
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1742.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/parameter-argument-mismatch"
},
{
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1751.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays"
},
{
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1921.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors"
Expand Down Expand Up @@ -1456,6 +1460,14 @@
"source_path_from_root": "/docs/csharp/misc/cs0206.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/ref-modifiers-errors"
},
{
"source_path_from_root": "/docs/csharp/misc/cs0225.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays"
},
{
"source_path_from_root": "/docs/csharp/misc/cs0231.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays"
},
{
"source_path_from_root": "/docs/csharp/misc/cs0248.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/feature-version-errors"
Expand All @@ -1480,6 +1492,10 @@
"source_path_from_root": "/docs/csharp/misc/cs0440.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors"
},
{
"source_path_from_root": "/docs/csharp/misc/cs0466.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays"
},
{
"source_path_from_root": "/docs/csharp/misc/cs0514.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/constructor-errors#static-constructors"
Expand Down Expand Up @@ -1552,6 +1568,10 @@
"source_path_from_root": "/docs/csharp/misc/cs0655.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/parameter-argument-mismatch"
},
{
"source_path_from_root": "/docs/csharp/misc/cs0674.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays"
},
{
"source_path_from_root": "/docs/csharp/misc/cs0687.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors"
Expand All @@ -1572,6 +1592,10 @@
"source_path_from_root": "/docs/csharp/misc/cs0748.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/lambda-expression-errors#lambda-expression-parameters-and-returns"
},
{
"source_path_from_root": "/docs/csharp/misc/cs0758.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays"
},
{
"source_path_from_root": "/docs/csharp/misc/cs0765.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/expression-tree-restrictions"
Expand Down Expand Up @@ -1608,6 +1632,10 @@
"source_path_from_root": "/docs/csharp/misc/cs1016.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/parameter-argument-mismatch"
},
{
"source_path_from_root": "/docs/csharp/misc/cs1104.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays"
},
{
"source_path_from_root": "/docs/csharp/misc/cs1510.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/ref-modifiers-errors"
Expand All @@ -1632,6 +1660,10 @@
"source_path_from_root": "/docs/csharp/misc/cs1605.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/ref-modifiers-errors"
},
{
"source_path_from_root": "/docs/csharp/misc/cs1611.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays"
},
{
"source_path_from_root": "/docs/csharp/misc/cs1621.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/lambda-expression-errors#syntax-limitations-in-lambda-expressions"
Expand Down Expand Up @@ -1664,6 +1696,10 @@
"source_path_from_root": "/docs/csharp/misc/cs1657.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/ref-modifiers-errors"
},
{
"source_path_from_root": "/docs/csharp/misc/cs1670.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays"
},
{
"source_path_from_root": "/docs/csharp/misc/cs1673.md",
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/lambda-expression-errors#syntax-limitations-in-lambda-expressions"
Expand Down
41 changes: 0 additions & 41 deletions docs/csharp/language-reference/compiler-messages/cs1751.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ f1_keywords:
- "CS8952"
- "CS9170"
- "CS9175"
- "CS9226"
helpviewer_keywords:
- "CS0765"
- "CS0831"
Expand Down Expand Up @@ -92,6 +93,7 @@ helpviewer_keywords:
- "CS8952"
- "CS9170"
- "CS9175"
- "CS9226"
ms.date: 09/06/2023
---
# Resolve errors and warnings generated from expressions prohibited in expression trees
Expand Down Expand Up @@ -146,6 +148,7 @@ That's by design. The text closely matches the text of the compiler error / warn
- **CS8972** - *A lambda expression with attributes cannot be converted to an expression tree.*
- **CS9170** - *An expression tree may not contain an inline array access or conversion.*
- **CS9175** - *An expression tree may not contain a collection expression.*
- **CS9226** - *An expression tree may not contain an expanded form of non-array params collection parameter.*

## Expression tree restrictions

Expand Down Expand Up @@ -177,6 +180,7 @@ The following expressions are prohibited:
- Calls to methods that return by `ref` aren't allowed.
- [static abstract interface members](../keywords/interface.md#static-abstract-and-virtual-members) can't be accessed.
- [Inline arrays](../builtin-types/struct.md#inline-arrays).
- The `params` modifier is allowed only on single-dimensional arrays. Other collection types aren't allowed.

Other restrictions are:

Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/language-reference/compiler-messages/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "C# Compiler Errors"
title: "Compiler messages"
ms.date: 04/27/2021
ms.date: 05/21/2024
helpviewer_keywords:
- "C# language, compiler errors"
- "Visual C# compiler, errors"
Expand Down
142 changes: 142 additions & 0 deletions docs/csharp/language-reference/compiler-messages/params-arrays.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
---
title: Errors and warnings related to `params` arrays
description: This article helps you diagnose and correct compiler errors and warnings when you use the `params` modifier on method parameters.
f1_keywords:
- "CS0225"
- "CS0231"
- "CS0466"
- "CS0674"
- "CS0758"
- "CS1104"
- "CS1611"
- "CS1670"
- "CS1751"
- "CS9218"
- "CS9219"
- "CS9220"
- "CS9221"
- "CS9222"
- "CS9223"
- "CS9224"
- "CS9225"
- "CS9227"
- "CS9228"
helpviewer_keywords:
- "CS0225"
- "CS0231"
- "CS0466"
- "CS0674"
- "CS0758"
- "CS1104"
- "CS1611"
- "CS1670"
- "CS1751"
- "CS9218"
- "CS9219"
- "CS9220"
- "CS9221"
- "CS9222"
- "CS9223"
- "CS9224"
- "CS9225"
- "CS9227"
- "CS9228"
ms.date: 05/20/2024
---
# Errors and warnings related to the `params` modifier on method parameters

There are a few *errors* related to the `lock` statement and thread synchronization:

<!-- 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**](#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**](#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.*

## Method declaration rules

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

- **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.*

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

- 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.

In versions before C# 12, the `params` modifier can't be used on the parameter of an anonymous method or lambda expression.

## Parameter and argument type rules

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

- **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.*

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.

- **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.*

In versions before C# 13, the `params` modifier is allowed on single-dimensional arrays only. No other types were valid.

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).

## Other params errors

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

- **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.*

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>.

The compiler generates one of the final three errors in the preceding list when the code generated to create the collection type is invalid:

- The compiler emits **CS9223** when the code emitted to create the collection also contains a params collection of the same type. Typically, the `Add` method takes a `params` collection of the same type.
- The compiler emits **CS9224** when the `Create` method for the collection type is less accessible than the method that takes the `params` parameter of the collection type.
- The compiler emits **CS9225** when the collection type has a required member and the parameterless constructor doesn't initialize that member and have the <xref:System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute?displayProperty=nameWithType> on the parameterless constructor.

## 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)
Loading

0 comments on commit 3b1a1b6

Please sign in to comment.