Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 48 additions & 13 deletions standard/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ A number of attributes affect the language in some way. These attributes include
- `System.Runtime.CompilerServices.EnumeratorCancellationAttribute` ([§23.5.8](attributes.md#2358-the-enumeratorcancellation-attribute)), which is used to specify parameter for the cancellation token in an asynchronous iterator.
- `System.Runtime.CompilerServices.ModuleInitializer` ([§23.5.9](attributes.md#2359-the-moduleinitializer-attribute)), which is used to mark a method as a module initializer.
- `System.Runtime.CompilerServices.InterpolatedStringHandlerAttribute` and `System.Runtime.CompilerServices.InterpolatedStringHandlerArgumentAttribute`, which are used to declare a custom interpolated string expression handler ([§23.5.9.1](attributes.md#23591-custom-interpolated-string-expression-handlers)) and to call one of its constructors, respectively.
- System.Diagnostics.CodeAnalysis.UnscopedRefAttribute (§UnscopedRefAttribute), which allows an otherwise implicitly scoped ref to be treated as not being scoped.

The Nullable static analysis attributes ([§23.5.7](attributes.md#2357-code-analysis-attributes)) can improve the correctness of warnings generated for nullabilities and null states ([§8.9.5](types.md#895-nullabilities-and-null-states)).

Expand Down Expand Up @@ -927,19 +928,19 @@ The attributes in this subclause are used to provide additional information to s

The code-analysis attributes are declared in namespace `System.Diagnostics.CodeAnalysis`.

**Attribute** | **Meaning**
------------------ | ------------------
`AllowNull` ([§23.5.7.2](attributes.md#23572-the-allownull-attribute)) | A non-nullable argument may be null.
`DisallowNull` ([§23.5.7.3](attributes.md#23573-the-disallownull-attribute)) | A nullable argument should never be null.
`MaybeNull` ([§23.5.7.6](attributes.md#23576-the-maybenull-attribute)) | A non-nullable return value may be null.
`NotNull` ([§23.5.7.10](attributes.md#235710-the-notnull-attribute)) | A nullable return value will never be null.
`MaybeNullWhen` ([§23.5.7.7](attributes.md#23577-the-maybenullwhen-attribute)) | A non-nullable argument may be null when the method returns the specified `bool` value.
`NotNullWhen` ([§23.5.7.12](attributes.md#235712-the-notnullwhen-attribute)) | A nullable argument won't be null when the method returns the specified `bool` value.
`NotNullIfNotNull` ([§23.5.7.11](attributes.md#235711-the-notnullifnotnull-attribute)) | A return value isn't null if the argument for the specified parameter isn't null.
`MemberNotNull` ([§23.5.7.8](attributes.md#23578-the-membernotnull-attribute)) | The listed member won't be null when the method returns.
`MemberNotNullWhen` ([§23.5.7.9](attributes.md#23579-the-membernotnullwhen-attribute)) | The listed member won't be null when the method returns the specified `bool` value.
`DoesNotReturn` ([§23.5.7.4](attributes.md#23574-the-doesnotreturn-attribute)) | This method never returns.
`DoesNotReturnIf` ([§23.5.7.5](attributes.md#23575-the-doesnotreturnif-attribute)) | This method never returns if the associated `bool` parameter has the specified value.
| **Attribute** | **Meaning** |
| ------------------ | ------------------ |
| `AllowNull` ([§23.5.7.2](attributes.md#23572-the-allownull-attribute)) | A non-nullable argument may be null. |
| `DisallowNull` ([§23.5.7.3](attributes.md#23573-the-disallownull-attribute)) | A nullable argument should never be null. |
| `MaybeNull` ([§23.5.7.6](attributes.md#23576-the-maybenull-attribute)) | A non-nullable return value may be null. |
| `NotNull` ([§23.5.7.10](attributes.md#235710-the-notnull-attribute)) | A nullable return value will never be null. |
| `MaybeNullWhen` ([§23.5.7.7](attributes.md#23577-the-maybenullwhen-attribute)) | A non-nullable argument may be null when the method returns the specified `bool` value. |
| `NotNullWhen` ([§23.5.7.12](attributes.md#235712-the-notnullwhen-attribute)) | A nullable argument won't be null when the method returns the specified `bool` value. |
| `NotNullIfNotNull` ([§23.5.7.11](attributes.md#235711-the-notnullifnotnull-attribute)) | A return value isn't null if the argument for the specified parameter isn't null. |
| `MemberNotNull` ([§23.5.7.8](attributes.md#23578-the-membernotnull-attribute)) | The listed member won't be null when the method returns. |
| `MemberNotNullWhen` ([§23.5.7.9](attributes.md#23579-the-membernotnullwhen-attribute)) | The listed member won't be null when the method returns the specified `bool` value. |
| `DoesNotReturn` ([§23.5.7.4](attributes.md#23574-the-doesnotreturn-attribute)) | This method never returns. |
| `DoesNotReturnIf` ([§23.5.7.5](attributes.md#23575-the-doesnotreturnif-attribute)) | This method never returns if the associated `bool` parameter has the specified value. |

The following subclauses in [§23.5.7](attributes.md#2357-code-analysis-attributes) are conditionally normative.

Expand Down Expand Up @@ -1184,6 +1185,40 @@ Specifies that a nullable argument will not be `null` when the method returns th
>
> *end example*

### §UnscopedRefAttribute The UnscopedRef attribute

There are several cases in which a ref is treated as being implicitly scoped (§scoped-modifier); that is, the ref is not allowed to escape a method. For example:

- `this` for struct instance methods.
- ref parameters that refer to ref struct types.
- out parameters.

This attribute is used in those situations where the ref should be allowed to escape.

This attribute may can be applied to any `ref` and it changes the ref-safe-context to be one level wider than its default. For example:

| UnscopedRef applied to | Original ref-safe-context | New ref-safe-context |
| --- | --- | --- |
| instance member | function-member | return-only |
| `in` / `ref` parameter | return-only | caller-context |
| `out` parameter | function-member | return-only |

When applying this attribute to an instance method of a struct it modifies the implicit `this` parameter; that is, `this` acts as an unannotated `ref` of the same type.

An instance method or property annotated with `[UnscopedRef]` has the ref-safe-context of `this` set to the *caller-context*.

A member annotated with `[UnscopedRef]` may not implement an interface.

It is an error to use `[UnscopedRef]` on

- A member that is not declared on a `struct`.
- A `static` member, `init` member, or constructor on a `struct`.
- A parameter marked `scoped`.
- A parameter passed by value.
- A parameter passed by reference that is not implicitly scoped.

See §scoped-modifier for more information.

### 23.5.8 The EnumeratorCancellation attribute

Specifies the parameter representing the `CancellationToken` for an asynchronous iterator ([§15.15](classes.md#1515-synchronous-and-asynchronous-iterators)). The argument for this parameter shall be combined with the argument passed to `IAsyncEnumerable<T>.GetAsyncEnumerator(CancellationToken)`. This combined token shall be polled by `IAsyncEnumerator<T>.MoveNextAsync()` ([§15.15.5.2](classes.md#151552-advance-the-enumerator)). The tokens shall be combined into a single token as if by `CancellationToken.CreateLinkedTokenSource` and its `Token` property. The combined token will be canceled if either of the two source tokens are canceled. The combined token is seen as the argument to the asynchronous iterator method ([§15.15](classes.md#1515-synchronous-and-asynchronous-iterators)) in the body of that method.
Expand Down
8 changes: 4 additions & 4 deletions standard/basic-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -717,11 +717,11 @@ The following accessibility constraints exist:

Methods, instance constructors, indexers, and operators are characterized by their ***signature***s:

- The signature of a method consists of the name of the method, the number of type parameters, and the type and parameter-passing mode of each of its parameters, considered in the order left to right. For these purposes, any type parameter of the method that occurs in the type of a parameter is identified not by its name, but by its ordinal position in the type parameter list of the method. The signature of a method specifically does not include the return type, parameter names, type parameter names, type parameter constraints, the `params` or `this` parameter modifiers, nor whether parameters are required or optional.
- The signature of a method consists of the name of the method, the number of type parameters, and the type and parameter-passing mode of each of its parameters, considered in the order left to right. For these purposes, any type parameter of the method that occurs in the type of a parameter is identified not by its name, but by its ordinal position in the type parameter list of the method. The signature of a method specifically does not include the return type, parameter names, type parameter names, type parameter constraints, the `params`, `scoped`, or `this` parameter modifiers, nor whether parameters are required or optional.
- The signature of an instance constructor consists of the type and parameter-passing mode of each of its parameters, considered in the order left to right. The signature of an instance constructor specifically does not include the `params` modifier that may be specified for the right-most parameter, nor whether parameters are required or optional.
- The signature of an indexer consists of the type of each of its parameters, considered in the order left to right. The signature of an indexer specifically does not include the element type, nor does it include the `params` modifier that may be specified for the right-most parameter, nor whether parameters are required or optional.
- The signature of an operator consists of the name of the operator and the type of each of its parameters, considered in the order left to right. The signature of an operator specifically does not include the result type.
- The signature of a conversion operator consists of the source type and the target type. The implicit or explicit classification of a conversion operator is not part of the signature.
- The signature of an indexer consists of the type of each of its parameters, considered in the order left to right. The signature of an indexer specifically does not include the element type, or the `scoped` modifier, nor does it include the `params` modifier that may be specified for the right-most parameter, or the `scoped` modifier, nor whether parameters are required or optional.
- The signature of an operator consists of the name of the operator and the type of each of its parameters, considered in the order left to right. The signature of an operator specifically does not include the result type or the `scoped` modifier.
- The signature of a conversion operator consists of the source type and the target type. The implicit or explicit classification of a conversion operator is not part of the signature nor is the `scoped` modifier.
- Two signatures of the same member kind (method, instance constructor, indexer or operator) are considered to be the *same signatures* if they have the same name, number of type parameters, number of parameters, and parameter-passing modes, and an identity conversion exists between the types of their corresponding parameters ([§10.2.2](conversions.md#1022-identity-conversion)).

Signatures are the enabling mechanism for ***overloading*** of members in classes, structs, and interfaces:
Expand Down
13 changes: 9 additions & 4 deletions standard/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2270,8 +2270,9 @@ default_argument

parameter_modifier
: parameter_mode_modifier
| 'this' parameter_mode_modifier?
| parameter_mode_modifier? 'this'
| 'this' 'scoped'? parameter_mode_modifier?
| 'scoped'? parameter_mode_modifier? 'this'
| 'scoped' parameter_mode_modifier?
;

parameter_mode_modifier
Expand All @@ -2287,7 +2288,11 @@ parameter_array

The parameter list consists of one or more comma-separated parameters of which only the last may be a *parameter_array*.

A *fixed_parameter* consists of an optional set of *attributes* ([§23](attributes.md#23-attributes)); an optional `in`, `out`, `ref`, or `this` modifier; a *type*; an *identifier*; and an optional *default_argument*. Each *fixed_parameter* declares a parameter of the given type with the given name. The `this` modifier designates the method as an extension method and is only allowed on the first parameter of a static method in a non-generic, non-nested static class. If the parameter is a `struct` type or a type parameter constrained to a `struct`, the `this` modifier may be combined with either the `ref` or `in` modifier, but not the `out` modifier. Extension methods are further described in [§15.6.10](classes.md#15610-extension-methods). A *fixed_parameter* with a *default_argument* is known as an ***optional parameter***, whereas a *fixed_parameter* without a *default_argument* is a ***required parameter***. A required parameter shall not appear after an optional parameter in a *parameter_list*.
A *fixed_parameter* consists of an optional set of *attributes* ([§23](attributes.md#23-attributes)); an optional `this` modifier; an optional `scoped` modifier; an optional `in`, `out`, `ref` modifier; a *type*; an *identifier*; and an optional *default_argument*. Each *fixed_parameter* declares a parameter of the given type with the given name. The `this` modifier designates the method as an extension method and is only allowed on the first parameter of a static method in a non-generic, non-nested static class. If the parameter is a `struct` type or a type parameter constrained to a `struct`, the `this` modifier may be combined with either the `ref` or `in` modifier, but not the `out` modifier. Extension methods are further described in [§15.6.10](classes.md#15610-extension-methods). A *fixed_parameter* with a *default_argument* is known as an ***optional parameter***, whereas a *fixed_parameter* without a *default_argument* is a ***required parameter***. A required parameter shall not appear after an optional parameter in a *parameter_list*.

An output parameter implicitly has the `scoped` modifier.

For a discussion of `scoped`, see §scoped-modifier.

A parameter with a `ref`, `out` or `this` modifier cannot have a *default_argument*. An input parameter may have a *default_argument*. The *expression* in a *default_argument* shall be one of the following:

Expand Down Expand Up @@ -2335,7 +2340,7 @@ The following kinds of parameters exist:
- Reference parameters ([§15.6.2.3.3](classes.md#156233-reference-parameters)).
- Parameter arrays ([§15.6.2.4](classes.md#15624-parameter-arrays)).

> *Note*: As described in [§7.6](basic-concepts.md#76-signatures-and-overloading), the `in`, `out`, and `ref` modifiers are part of a method’s signature, but the `params` modifier is not. *end note*
> *Note*: As described in [§7.6](basic-concepts.md#76-signatures-and-overloading), the `in`, `out`, and `ref` modifiers are part of a method’s signature, but the `params` and `scoped` modifiers are not. *end note*

#### 15.6.2.2 Value parameters

Expand Down
Loading