Skip to content

Commit 230e59d

Browse files
authored
Add ref readonly parameters feature
1 parent 4fe298a commit 230e59d

1 file changed

Lines changed: 12 additions & 11 deletions

File tree

standard/expressions.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ Every function member and delegate invocation includes an argument list, which p
553553
- For events, the argument list consists of the expression specified as the right operand of the `+=` or `-=` operator.
554554
- For user-defined operators, the argument list consists of the single operand of the unary operator or the two operands of the binary operator.
555555
556-
The arguments of properties ([§15.7](classes.md#157-properties)) and events ([§15.8](classes.md#158-events)) are always passed as value parameters ([§15.6.2.2](classes.md#15622-value-parameters)). The arguments of user-defined operators ([§15.10](classes.md#1510-operators)) are always passed as value parameters ([§15.6.2.2](classes.md#15622-value-parameters)) or input parameters ([§9.2.8](variables.md#928-input-parameters)). The arguments of indexers ([§15.9](classes.md#159-indexers)) are always passed as value parameters ([§15.6.2.2](classes.md#15622-value-parameters)), input parameters ([§9.2.8](variables.md#928-input-parameters)), or parameter arrays ([§15.6.2.4](classes.md#15624-parameter-arrays)). Output and reference parameters are not supported for these categories of function members.
556+
The arguments of properties ([§15.7](classes.md#157-properties)) and events ([§15.8](classes.md#158-events)) are always passed as value parameters ([§15.6.2.2](classes.md#15622-value-parameters)). The arguments of user-defined operators ([§15.10](classes.md#1510-operators)) are always passed as value parameters ([§15.6.2.2](classes.md#15622-value-parameters)) or input parameters ([§9.2.8](variables.md#928-input-parameters)). The arguments of indexers ([§15.9](classes.md#159-indexers)) are always passed as value parameters ([§15.6.2.2](classes.md#15622-value-parameters)), input parameters ([§9.2.8](variables.md#928-input-parameters)), reference parameters of kind `ref readonly` ([§15.6.2.3.3](classes.md#156233-reference-parameters)), or parameter arrays ([§15.6.2.4](classes.md#15624-parameter-arrays)). Output and reference parameters of kind `ref` are not supported for these categories of function members.
557557
558558
The arguments of an instance constructor, method, indexer, or delegate invocation are specified as an *argument_list*:
559559
@@ -582,12 +582,12 @@ An *argument_list* consists of one or more *argument*s, separated by commas. Eac
582582

583583
The *argument_value* can take one of the following forms:
584584

585-
- An *expression*, indicating that the argument is passed as a value parameter or is transformed into an input parameter and then passed as that, as determined by ([§12.6.4.2](expressions.md#12642-applicable-function-member) and described in [§12.6.2.3](expressions.md#12623-run-time-evaluation-of-argument-lists).
586-
- The keyword `in` optionally followed by `scoped`, followed by a *variable_reference* ([§9.5](variables.md#95-variable-references)), indicating that the argument is passed as an input parameter ([§15.6.2.3.2](classes.md#156232-input-parameters)). A variable shall be definitely assigned ([§9.4](variables.md#94-definite-assignment)) before it can be passed as an input parameter. For a discussion of `scoped`, see [§9.7.3](variables.md#973-the-scoped-modifier).
585+
- An *expression*, indicating that the argument is passed as a value parameter or is transformed into an input or `ref readonly` reference parameter and then passed as that, as determined by ([§12.6.4.2](expressions.md#12642-applicable-function-member) and described in [§12.6.2.3](expressions.md#12623-run-time-evaluation-of-argument-lists).
586+
- The keyword `in` optionally followed by `scoped`, followed by a *variable_reference* ([§9.5](variables.md#95-variable-references)), indicating that the argument is passed as an input parameter ([§15.6.2.3.2](classes.md#156232-input-parameters)) or is transformed into a `ref readonly` reference parameter ([§15.6.2.3.3](classes.md#156233-reference-parameters)) and then passed as that. A variable shall be definitely assigned ([§9.4](variables.md#94-definite-assignment)) before it can be passed as an input parameter. For a discussion of `scoped`, see [§9.7.3](variables.md#973-the-scoped-modifier).
587587
- The keyword `ref` optionally followed by `scoped`, followed by a *variable_reference* ([§9.5](variables.md#95-variable-references)), indicating that the argument is passed as a reference parameter ([§15.6.2.3.3](classes.md#156233-reference-parameters)). A variable shall be definitely assigned ([§9.4](variables.md#94-definite-assignment)) before it can be passed as a reference parameter. For a discussion of `scoped`, see [§9.7.3](variables.md#973-the-scoped-modifier).
588588
- The keyword `out` optionally followed by `scoped`, optionally followed by a *variable_reference* ([§9.5](variables.md#95-variable-references)), indicating that the argument is passed as an output parameter ([§15.6.2.3.4](classes.md#156234-output-parameters)). A variable is considered definitely assigned ([§9.4](variables.md#94-definite-assignment)) following a function member invocation in which the variable is passed as an output parameter. For a discussion of `scoped`, see [§9.7.3](variables.md#973-the-scoped-modifier).
589589

590-
The form determines the ***parameter-passing mode*** of the argument: *value*, *input*, *reference*, or *output*, respectively. However, as mentioned above, an argument with value passing mode, might be transformed into one with input passing mode.
590+
The form determines the ***parameter-passing mode*** of the argument: *value*, *input*, *reference*, or *output*, respectively. However, as mentioned above, an argument with value passing mode, might be transformed into one with input or `ref readonly` reference passing mode.
591591

592592
Passing a volatile field ([§15.5.4](classes.md#1554-volatile-fields)) as an input, output, or reference parameter causes a warning, since the field cannot be treated as volatile by the invoked method.
593593

@@ -622,19 +622,19 @@ During the run-time processing of a function member invocation ([§12.6.6](expre
622622

623623
- For a value argument, if the parameter’s passing mode is value
624624
- the argument expression is evaluated and an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) to the corresponding parameter type is performed. The resulting value becomes the initial value of the value parameter in the function member invocation.
625-
- otherwise, the parameter’s passing mode is input. If the argument is a variable reference and there exists an identity conversion ([§10.2.2](conversions.md#1022-identity-conversion)) between the argument’s type and the parameter’s type, the resulting storage location becomes the storage location represented by the parameter in the function member invocation. Otherwise, a storage location is created with the same type as that of the corresponding parameter. The argument expression is evaluated and an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) to the corresponding parameter type is performed. The resulting value is stored within that storage location. That storage location is represented by the input parameter in the function member invocation.
625+
- otherwise, the parameter’s passing mode is input or ref readonly. If the argument is a variable reference and there exists an identity conversion ([§10.2.2](conversions.md#1022-identity-conversion)) between the argument’s type and the parameter’s type, the resulting storage location becomes the storage location represented by the parameter in the function member invocation. Otherwise, a storage location is created with the same type as that of the corresponding parameter. The argument expression is evaluated and an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) to the corresponding parameter type is performed. The resulting value is stored within that storage location. That storage location is represented by the input parameter in the function member invocation.
626626

627627
> *Example*: Given the following declarations and method calls:
628628
>
629-
> <!-- Example: {template:"standalone-console-without-using", name:"Run-timeEvalOfArgLists3", replaceEllipsis:true} -->
629+
> <!-- Example: {template:"standalone-console-without-using", name:"Run-timeEvalOfArgLists3", replaceEllipsis:true, expectedWarnings:["CS9192","CS9193"]} -->
630630
> ```csharp
631-
> static void M1(in int p1) { ... }
631+
> static void M1(in int p1, ref readonly int p2) { ... }
632632
> int i = 10;
633-
> M1(i); // i is passed as an input argument
634-
> M1(i + 5); // transformed to a temporary input argument
633+
> M1(i, i); // i is passed as input and reference arguments
634+
> M1(i + 5, i + 7); // both transformed to temporary arguments
635635
> ```
636636
>
637-
> In the `M1(i)` method call, `i` itself is passed as an input argument, because it is classified as a variable and has the same type `int` as the input parameter. In the `M1(i + 5)` method call, an unnamed `int` variable is created, initialized with the arguments value, and then passed as an input argument. See [§12.6.4.2](expressions.md#12642-applicable-function-member) and12.6.4.4](expressions.md#12644-better-parameter-passing-mode).
637+
> In the `M1(i, i)` method call, `i` itself is passed as an input and a reference argument, respectively, because it is classified as a variable and has the same type `int` as the corresponding input and reference parameters. In the `M1(i + 5, i + 7)` method call, two unnamed `int` variables are created, initialized with the corresponding arguments value, and then passed as an input and reference argument, respectively. See [§12.6.4.2](expressions.md#12642-applicable-function-member) and12.6.4.4](expressions.md#12644-better-parameter-passing-mode).
638638
>
639639
> *end example*
640640
@@ -1076,6 +1076,7 @@ A function member is said to be an ***applicable function member*** with respect
10761076
- for a reference or output parameter, there is an identity conversion between the type of the argument expression (if any) and the type of the corresponding parameter, or
10771077
- for an input parameter when the corresponding argument has the `in` modifier, there is an identity conversion between the type of the argument expression (if any) and the type of the corresponding parameter, or
10781078
- for an input parameter when the corresponding argument omits the `in` modifier, an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) exists from the argument expression to the type of the corresponding parameter.
1079+
- for a `ref readonly` parameter when the corresponding argument omits the `ref` modifier, an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) exists from the argument expression to the type of the corresponding parameter.
10791080
10801081
For a function member that includes a parameter array, if the function member is applicable by the above rules, it is said to be applicable in its ***normal form***. If a function member that includes a parameter array is not applicable in its normal form, the function member might instead be applicable in its ***expanded form***:
10811082
@@ -1084,7 +1085,7 @@ For a function member that includes a parameter array, if the function member is
10841085
- the parameter-passing mode of the argument is identical to the parameter-passing mode of the corresponding parameter, and:
10851086
- for a fixed value parameter or a value parameter created by the expansion, an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) exists from the argument expression to the type of the corresponding parameter; or
10861087
- for a by-reference parameter, the type of the argument expression is identical to the type of the corresponding parameter.
1087-
- the parameter-passing mode of the argument is value, and the parameter-passing mode of the corresponding parameter is input, and an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) exists from the argument expression to the type of the corresponding parameter.
1088+
- the parameter-passing mode of the argument is value, and the parameter-passing mode of the corresponding parameter is input or `ref readonly`, and an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) exists from the argument expression to the type of the corresponding parameter.
10881089
10891090
When the implicit conversion from the argument type to the parameter type of an input parameter is a dynamic implicit conversion ([§10.2.10](conversions.md#10210-implicit-dynamic-conversions)), the results are undefined.
10901091

0 commit comments

Comments
 (0)