Skip to content

Commit 13eca45

Browse files
committed
Address existing comments.
Also, edit after moving text around.
1 parent 4ad1b60 commit 13eca45

File tree

1 file changed

+46
-29
lines changed

1 file changed

+46
-29
lines changed

standard/classes.md

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2152,15 +2152,15 @@ A declaration has a valid combination of modifiers if all of the following are t
21522152
- If the declaration includes the `private` modifier, then the declaration does not include any of the following modifiers: `virtual`, `override`, or `abstract`.
21532153
- If the declaration includes the `sealed` modifier, then the declaration also includes the `override` modifier.
21542154
- If the declaration includes the `partial` modifier, then it does not include the modifier `abstract`.
2155-
- If the declaration is for a restricted partial method ([§15.6.9](classes.md#1569-partial-methods)), then it does not include any of the following modifiers: `new`, `public`, `protected`, `internal`, `private`, `virtual`, `sealed`, `override`, or `extern`.
2155+
- If the declaration is for a restricted partial method (§restricted-partial-methods), then it does not include any of the following modifiers: `new`, `public`, `protected`, `internal`, `private`, `virtual`, `sealed`, `override`, or `extern`.
21562156

21572157
Methods are classified according to what, if anything, they return:
21582158

21592159
- If `ref` is present, the method is ***returns-by-ref*** and returns a *variable reference*, that is optionally read-only;
21602160
- Otherwise, if *return_type* is `void`, the method is ***returns-no-value*** and does not return a value;
21612161
- Otherwise, the method is ***returns-by-value*** and returns a value.
21622162

2163-
The *return_type* of a returns-by-value or returns-no-value method declaration specifies the type of the result, if any, returned by the method. Only a returns-no-value method may include the `partial` modifier ([§15.6.9](classes.md#1569-partial-methods)). If the declaration includes the `async` modifier then *return_type* for a restricted partial method shall be `void` or the method returns-by-value and the return type is a *task type* ([§15.14.1](classes.md#15141-general)).
2163+
The *return_type* of a returns-by-value or returns-no-value method declaration specifies the type of the result, if any, returned by the method. If the declaration includes the `async` modifier then *return_type* shall be `void` or the method returns-by-value and the return type is a *task type* ([§15.14.1](classes.md#15141-general)).
21642164

21652165
The *ref_return_type* of a returns-by-ref method declaration specifies the type of the variable referenced by the *variable_reference* returned by the method.
21662166

@@ -2389,7 +2389,7 @@ For a `struct` type, within an instance method, instance accessor ([§12.2.1](ex
23892389
23902390
A parameter declared with an `out` modifier is an ***output parameter***. For definite-assignment rules, see [§9.2.7](variables.md#927-output-parameters).
23912391
2392-
A method declared as a restricted partial method ([§15.6.9](classes.md#1569-partial-methods)) shall not have output parameters.
2392+
A method declared as a restricted partial method (§restricted-partial-methods) shall not have output parameters.
23932393
23942394
> *Note*: Output parameters are typically used in methods that produce multiple return values. *end note*
23952395
<!-- markdownlint-disable MD028 -->
@@ -3027,19 +3027,28 @@ The mechanism by which linkage to an external method is achieved is implementati
30273027
30283028
### 15.6.9 Partial methods
30293029
3030+
#### §partial-methods-general General
3031+
30303032
When a *method declaration* includes a `partial` modifier, that method is said to be a ***partial method***. Partial methods may only be declared as members of partial types ([§15.2.7](classes.md#1527-partial-type-declarations)).
30313033
3032-
Partial methods may be defined in one part of a type declaration and implemented in another, or be defined and implemented in the same part.
3034+
There are two versions of partial methods: restricted and unrestricted. A ***restricted partial method***restricted-partial-methods) has no explicit access modifiers, and is implicitly private. An ***unrestricted partial method*** (§unrestricted-partial-methods) is a partial method that includes one or more explicit access modifiers.
3035+
3036+
There are two kinds of partial method declarations:
30333037
3034-
There are two kinds of partial method declarations: If the body of the method declaration is a semicolon, the declaration is said to be a ***defining partial method declaration***. Otherwise, the declaration is said to be an ***implementing partial method declaration***. Across the parts of a type declaration, there may be only one defining partial method declaration with a given signature, and there may be only one implementing partial method declaration with a given signature. If an implementing partial method declaration is given, a corresponding defining partial method declaration shall exist, and the declarations shall match as specified in the following:
3038+
- A method with an *expression-body* or a *block-body* or is declared with the `extern` modifier is said to be an ***implementing partial method declaration***.
3039+
- Otherwise, a method declaration where the body of the method declaration is a semicolon is said to be a ***defining partial method declaration***.
30353040
3036-
- The declarations shall have the same modifiers (although not necessarily in the same order), method name, number of type parameters, and number of parameters. In the case of private accessibility, both shall be implicitly private (that is, with no accessibility modifier) or both shall be explicitly `private`.
3041+
Across the parts of a type declaration, there shall be exactly one defining partial method declaration with a given signature. For an implementing partial method declaration is given, a corresponding defining partial method declaration shall exist, and the declarations shall match as specified in the following:
3042+
3043+
- The declarations shall have the same method name, number of type parameters, and number of parameters.
3044+
- The declarations shall have the same modifiers except for the `async` and `extern` modifiers. The `async` and `extern` modifiers are allowed only on the implementing partial method declaration.
30373045
- Corresponding parameters in the declarations shall have the same modifiers (although not necessarily in the same order) and the same types (modulo differences in type parameter names).
30383046
- Corresponding type parameters in the declarations shall have the same constraints (modulo differences in type parameter names).
3047+
-
30393048
3040-
Over time, the specification for partial methods has evolved, resulting in restricted and unrestricted versions. A ***restricted partial method*** has no explicit access modifiers (and is implicitly private), has a `void` return type, and has no out parameters. An ***unrestricted partial method*** is a partial method that has explicit access modifiers, a non-`void` return type, or any out parameters.
3049+
Partial methods may be defined in one part of a type declaration and implemented in another, or be defined and implemented in the same part.
30413050
3042-
For a restricted partial method, the implementation is optional; if no part implements the partial method, the partial method declaration and all calls to it are removed from the type declaration resulting from the combination of the parts. For an unrestricted partial method both the definition and implementation shall exist.
3051+
For an unrestricted partial method both the definition and implementation shall exist.
30433052
30443053
In *method_declaration*, the identifier `partial` is recognized as a contextual keyword ([§6.4.4](lexical-structure.md#644-keywords)) only if it immediately precedes the *return_type*. A partial method cannot explicitly implement interface methods.
30453054
@@ -3067,12 +3076,8 @@ In *method_declaration*, the identifier `partial` is recognized as a contextual
30673076
>
30683077
> *end example*
30693078
3070-
Only a defining partial method participates in overload resolution. As such, in the case of a restricted partial method, whether or not an implementing declaration is given, invocation expressions may resolve to invocations of the partial method.
3079+
Only a defining partial method participates in overload resolution.
30713080
3072-
> *Note*: Because a restricted partial method always returns `void`, such invocation expressions will always be expression statements. Furthermore, because a restricted partial method is implicitly `private`, such statements will always occur within one of the parts of the type declaration within which the partial method is declared. *end note*
3073-
<!-- markdownlint-disable MD028 -->
3074-
3075-
<!-- markdownlint-enable MD028 -->
30763081
> *Note*: The definition of matching defining and implementing partial method declarations does not require parameter names to match. This can produce *surprising*, albeit *well defined*, behaviour when named arguments ([§12.6.2.1](expressions.md#12621-general)) are used. For example, given the defining partial method declaration for `M` in one file, and the implementing partial method declaration in another file:
30773082
>
30783083
> <!-- Example: {template:"standalone-lib-without-using", name:"PartialMethods1", "expectedErrors":["CS1739"], "expectedWarnings":["CS8826"]} -->
@@ -3095,25 +3100,12 @@ Only a defining partial method participates in overload resolution. As such, in
30953100
>
30963101
> *end note*
30973102
3098-
If a restricted partial method has no implementation, any expression statement invoking it is simply removed from the combined type declaration. Thus, the invocation expression, including any subexpressions, has no effect at run-time. The partial method itself is also removed and will not be a member of the combined type declaration.
3099-
31003103
If an implementing declaration exists for a given partial method, the invocations of the partial methods are retained. The partial method gives rise to a method declaration similar to the implementing partial method declaration except for the following:
31013104
3102-
- The `partial` modifier is not included.
3103-
3105+
- All modifiers except the `partial` modifier are combined, including any `extern` or `async` modifier declared on the implementing declaration.
31043106
- The attributes in the resulting method declaration are the combined attributes of the defining and the implementing partial method declaration in unspecified order. Duplicates are not removed.
3105-
31063107
- The attributes on the parameters of the resulting method declaration are the combined attributes of the corresponding parameters of the defining and the implementing partial method declaration in unspecified order. Duplicates are not removed.
3107-
3108-
If a defining declaration but not an implementing declaration is given for a restricted partial method `M`, the following restrictions apply:
3109-
3110-
- It is a compile-time error to create a delegate from `M` ([§12.8.17.5](expressions.md#128175-delegate-creation-expressions)).
3111-
3112-
- It is a compile-time error to refer to `M` inside an anonymous function that is converted to an expression tree type ([§8.6](types.md#86-expression-tree-types)).
3113-
3114-
- Expressions occurring as part of an invocation of `M` do not affect the definite assignment state ([§9.4](variables.md#94-definite-assignment)), which can potentially lead to compile-time errors.
3115-
3116-
- `M` cannot be the entry point for an application ([§7.1](basic-concepts.md#71-application-startup)).
3108+
- Any default arguments (§15.6.2) in the implementing declaration are removed.
31173109
31183110
Partial methods are useful for allowing one part of a type declaration to customize the behavior of another part, e.g., one that is generated by a tool. Consider the following partial class declaration:
31193111
@@ -3197,6 +3189,31 @@ class Customer
31973189
}
31983190
```
31993191

3192+
#### §restricted-partial-methods Restricted partial methods
3193+
3194+
A restricted partial method shall have a `void` return type, and shall not declare out parameters. There shall be zero or one implementing declaration for each defining declaration. If no part implements the partial method, the partial method declaration and all calls to it are removed from the type declaration resulting from the combination of the parts. Whether or not an implementing declaration is given, invocation expressions may resolve to invocations of the partial method.
3195+
3196+
The implementing member for a restricted partial method shall not be an external method (§15.6.8).
3197+
3198+
> *Note*: Because a restricted partial method always returns `void`, such invocation expressions will always be expression statements. Furthermore, because a restricted partial method is implicitly `private`, such statements will always occur within one of the parts of the type declaration within which the partial method is declared. *end note*
3199+
3200+
If a restricted partial method has no implementation, any expression statement invoking it is removed from the combined type declaration. Thus, the invocation expression, including any subexpressions, has no effect at run-time. The partial method itself is also removed and will not be a member of the combined type declaration.
3201+
3202+
If a defining declaration but not an implementing declaration is given for a restricted partial method `M`, the following restrictions apply:
3203+
3204+
- It is a compile-time error to create a delegate from `M` ([§12.8.17.5](expressions.md#128175-delegate-creation-expressions)).
3205+
- It is a compile-time error to refer to `M` inside an anonymous function that is converted to an expression tree type ([§8.6](types.md#86-expression-tree-types)).
3206+
- Expressions occurring as part of an invocation of `M` do not affect the definite assignment state ([§9.4](variables.md#94-definite-assignment)), which can potentially lead to compile-time errors.
3207+
- `M` cannot be the entry point for an application ([§7.1](basic-concepts.md#71-application-startup)).
3208+
3209+
#### §unrestricted-partial-methods Unrestricted partial methods
3210+
3211+
An unrestriced partial method has an explicit access modifier. There shall be exactly one implementing partial method declaration.
3212+
3213+
The implementing declaration for an unrestricted partial method may be an external method (§15.6.8).
3214+
3215+
> *Note:* The `private` access modifier is required on both the ***defining partial method declaration*** and the ***implementing partial method declaration*** of an unrestricted partial method. *end note*
3216+
32003217
### 15.6.10 Extension methods
32013218

32023219
When the first parameter of a method includes the `this` modifier, that method is said to be an ***extension method***. Extension methods shall only be declared in non-generic, non-nested static classes. The first parameter of an extension method is restricted, as follows:
@@ -4264,7 +4281,7 @@ The *event_accessor_declarations* of an event specify the executable statements
42644281
42654282
The accessor declarations consist of an *add_accessor_declaration* and a *remove_accessor_declaration*. Each accessor declaration consists of the token add or remove followed by a *block*. The *block* associated with an *add_accessor_declaration* specifies the statements to execute when an event handler is added, and the *block* associated with a *remove_accessor_declaration* specifies the statements to execute when an event handler is removed.
42664283
4267-
Each *add_accessor_declaration* and *remove_accessor_declaration* corresponds to a method with a single value parameter of the event type, and a `void` return type. The implicit parameter of an event accessor is named `value`. When an event is used in an event assignment, the appropriate event accessor is used. Specifically, if the assignment operator is `+=` then the add accessor is used, and if the assignment operator is `–=` then the remove accessor is used. In either case, the right operand of the assignment operator is used as the argument to the event accessor. The block of an *add_accessor_declaration* or a *remove_accessor_declaration* shall conform to the rules for `void` methods described in [§15.6.9](classes.md#1569-partial-methods). In particular, `return` statements in such a block are not permitted to specify an expression.
4284+
Each *add_accessor_declaration* and *remove_accessor_declaration* corresponds to a method with a single value parameter of the event type, and a `void` return type. The implicit parameter of an event accessor is named `value`. When an event is used in an event assignment, the appropriate event accessor is used. Specifically, if the assignment operator is `+=` then the add accessor is used, and if the assignment operator is `–=` then the remove accessor is used. In either case, the right operand of the assignment operator is used as the argument to the event accessor. The block of an *add_accessor_declaration* or a *remove_accessor_declaration* shall conform to the rules for `void` methods described in §restricted-partial-methods. In particular, `return` statements in such a block are not permitted to specify an expression.
42684285
42694286
Since an event accessor implicitly has a parameter named `value`, it is a compile-time error for a local variable or constant declared in an event accessor to have that name.
42704287

0 commit comments

Comments
 (0)