From 4141989c7766ade8c3b1b77a96d10493dc647d65 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 2 Mar 2026 07:15:30 -0500 Subject: [PATCH 1/5] support extended nameof scope --- standard/basic-concepts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/standard/basic-concepts.md b/standard/basic-concepts.md index 79c65bcdc..856be2fba 100644 --- a/standard/basic-concepts.md +++ b/standard/basic-concepts.md @@ -689,11 +689,11 @@ The ***scope*** of a name is the region of program text within which it is possi - The scope of a type parameter declared by a *type_parameter_list* on a *struct_declaration* ([§16.2](structs.md#162-struct-declarations)) is the *struct_interfaces*, *type_parameter_constraints_clause*s, and *struct_body* (or *record_struct_body*) of that *struct_declaration*. - The scope of a type parameter declared by a *type_parameter_list* on an *interface_declaration* ([§19.2](interfaces.md#192-interface-declarations)) is the *interface_base*, *type_parameter_constraints_clause*s, and *interface_body* of that *interface_declaration*. - The scope of a type parameter declared by a *type_parameter_list* on a *delegate_declaration* ([§21.2](delegates.md#212-delegate-declarations)) is the *return_type*, *parameter_list*, and *type_parameter_constraints_clause*s of that *delegate_declaration*. -- The scope of a type parameter declared by a *type_parameter_list* on a *method_declaration* ([§15.6.1](classes.md#1561-general)) is the *method_declaration*. +- The scope of a type parameter declared by a *type_parameter_list* on a *method_declaration* ([§15.6.1](classes.md#1561-general)) is the *method_declaration* and `nameof` expressions in an attribute on the *method_declaration* or its parameters. - The scope of a member declared by a *class_member_declaration* ([§15.3.1](classes.md#1531-general)) is the *class_body* (or *record_class_body*) in which the declaration occurs. In addition, the scope of a class member extends to the *class_body* (or *record_class_body*) of those derived classes that are included in the accessibility domain ([§7.4.3](basic-concepts.md#743-accessibility-domains)) of the member. - The scope of a member declared by a *struct_member_declaration* ([§16.3](structs.md#163-struct-members)) is the *struct_body* (or *record_struct_body*) in which the declaration occurs. - The scope of a member declared by an *enum_member_declaration* ([§20.4](enums.md#204-enum-members)) is the *enum_body* in which the declaration occurs. -- The scope of a parameter declared in a *method_declaration* ([§15.6](classes.md#156-methods)) is the *method_body* or *ref_method_body* of that *method_declaration*. +- The scope of a parameter declared in a *method_declaration* ([§15.6](classes.md#156-methods)) is the *method_body* or *ref_method_body* of that *method_declaration* and `nameof` expressions in an attribute on the method declaration or its parameters. - The scope of a parameter declared in an *indexer_declaration* ([§15.9](classes.md#159-indexers)) is the *indexer_body* of that *indexer_declaration*. - The scope of a parameter declared in an *operator_declaration* ([§15.10](classes.md#1510-operators)) is the *operator_body* of that *operator_declaration*. - The scope of a parameter declared in a *constructor_declaration* ([§15.11](classes.md#1511-instance-constructors)) is the *constructor_initializer* and *block* of that *constructor_declaration*. From fffee03016b26dec9bb36b11246c31c1dc98bd4b Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 2 Mar 2026 07:19:59 -0500 Subject: [PATCH 2/5] support extended nameof scope --- standard/expressions.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/standard/expressions.md b/standard/expressions.md index 8bef27ddf..c175ba67e 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -1650,6 +1650,7 @@ A *simple_name* is either of the form `I` or of the form `I`, - If `e` is zero and the *simple_name* appears within a local variable declaration space ([§7.2](basic-concepts.md#72-declarations)) that directly contains a local variable, parameter (with the exception of discard parameters ([§12.22.2](expressions.md#12222-anonymous-function-signatures))), or constant with name `I`, then the *simple_name* refers to that local variable, parameter or constant and is classified as a variable or value. - If `e` is zero and the *simple_name* appears within a generic method declaration but outside the *attributes* of its *method_declaration*, and if that declaration includes a type parameter with name `I`, then the *simple_name* refers to that type parameter. +- If `e` is zero and the *simple_name* appears within a `nameof` expression in an attribute on the method declaration or its parameters, and if that declaration includes a parameter or type parameter with name `I`, then the *simple_name* refers to that parameter or type parameter. - Otherwise, for each instance type `T` ([§15.3.2](classes.md#1532-the-instance-type)), starting with the instance type of the immediately enclosing type declaration and continuing with the instance type of each enclosing class or struct declaration (if any): - If the declaration of `T` includes a primary constructor parameter `I` and the reference occurs within the `argument_list` of `T`’s `class_base` or within an initializer of a field, property or event of `T`, the result is the primary constructor parameter `I`. - Otherwise, if `e` is zero and the declaration of `T` includes a type parameter with name `I`, then the *simple_name* refers to that type parameter. @@ -5615,7 +5616,7 @@ The contextual keyword `var` shall not be used as an explicit return type in a * If an *explicit_anonymous_function_parameter_list* or an *implicit_anonymous_function_parameter_list* contains multiple *identifier*s `_`, each of those identifiers denotes a discard ([§9.2.9.2](variables.md#9292-discards)). Otherwise, any single *identifier* `_` denotes a parameter. -The *anonymous_function_signature* of an anonymous function defines the names and optionally the types and *attributes* of the parameters for the anonymous function. The scope of the non-discard parameters of the anonymous function is the *anonymous_function_body* ([§7.6](basic-concepts.md#76-scopes)). Together with the parameter list (if given) the anonymous-method-body constitutes a declaration space ([§7.2](basic-concepts.md#72-declarations)). It is thus a compile-time error for the name of a parameter of the anonymous function to match the name of a local variable, local constant or parameter whose scope includes the *anonymous_method_expression* or *lambda_expression*. +The *anonymous_function_signature* of an anonymous function defines the names and optionally the types and *attributes* of the parameters for the anonymous function. The scope of the non-discard parameters of the anonymous function is the *anonymous_function_body* ([§7.6](basic-concepts.md#76-scopes)) and `nameof` expressions in attributes placed on the anonymous function or its parameters. Together with the parameter list (if given) the anonymous-method-body constitutes a declaration space ([§7.2](basic-concepts.md#72-declarations)). It is thus a compile-time error for the name of a parameter of the anonymous function to match the name of a local variable, local constant or parameter whose scope includes the *anonymous_method_expression* or *lambda_expression*. > *Note*: Because discard parameters do not introduce a name into any scope, they do not conflict with other parameters, local variables, local constants, or other discards. *end note* From 4e3bcee883d7dcec18a5d73f331e749b473bac2a Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 2 Mar 2026 07:23:45 -0500 Subject: [PATCH 3/5] support extended nameof scope --- standard/classes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/standard/classes.md b/standard/classes.md index 12e4484cf..2d13f59b0 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -2218,7 +2218,7 @@ The name, the number of type parameters, and the parameter list of a method defi The name of a method shall differ from the names of all other non-methods declared in the same class. In addition, the signature of a method shall differ from the signatures of all other methods declared in the same class, and two methods declared in the same class shall not have signatures that differ solely by `in`, `out`, and `ref`. -The method’s *type_parameter*s are in scope throughout the *method_declaration*, and can be used to form types throughout that scope in *return_type* or *ref_return_type*, *method_body* or *ref_method_body*, and *type_parameter_constraints_clause*s but not in *attributes*. +The method’s *type_parameter*s are in scope throughout the *method_declaration*, and can be used to form types throughout that scope in *return_type* or *ref_return_type*, *method_body* or *ref_method_body*, and *type_parameter_constraints_clause*s but not in *attributes*, except within a `nameof` expression in *attributes*. All parameters and type parameters shall have different names. @@ -2306,9 +2306,9 @@ A *parameter_array* may occur after an optional parameter, but cannot have a def > > *end example* -A method declaration creates a separate declaration space ([§7.2](basic-concepts.md#72-declarations)) for parameters and type parameters. Names are introduced into this declaration space by the type parameter list and the parameter list of the method. The body of the method, if any, is considered to be nested within this declaration space. It is an error for two members of a method declaration space to have the same name. +A method declaration creates a separate declaration space ([§7.2](basic-concepts.md#72-declarations)) for parameters and type parameters. Names are introduced into this declaration space by the type parameter list and the parameter list of the method. These names are also in scope in `nameof` expressions in attributes placed on the method or its parameters. The body of the method, if any, is considered to be nested within this declaration space. It is an error for two members of a method declaration space to have the same name. -A method invocation ([§12.8.10.2](expressions.md#128102-method-invocations)) creates a copy, specific to that invocation, of the parameters and local variables of the method, and the argument list of the invocation assigns values or variable references to the newly created parameters. Within the *block* of a method, parameters can be referenced by their identifiers in *simple_name* expressions ([§12.8.4](expressions.md#1284-simple-names)). +A method invocation ([§12.8.10.2](expressions.md#128102-method-invocations)) creates a copy, specific to that invocation, of the parameters and local variables of the method, and the argument list of the invocation assigns values or variable references to the newly created parameters. Within the *block* of a method, parameters can be referenced by their identifiers in *simple_name* expressions ([§12.8.4](expressions.md#1284-simple-names)). Within a `nameof` expression in attributes placed on the method or its parameters, formal parameters can be referenced by their identifiers in *simple_name* expressions. The following kinds of parameters exist: From ce25a2bf66750b6fd5fc56c1200d6ca0abb5481e Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 2 Mar 2026 07:27:24 -0500 Subject: [PATCH 4/5] support extended nameof scope --- standard/delegates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/delegates.md b/standard/delegates.md index e22563e71..e4fab4a90 100644 --- a/standard/delegates.md +++ b/standard/delegates.md @@ -47,7 +47,7 @@ The delegate’s type name is *identifier*. As with methods ([§15.6.1](classes.md#1561-general)), if `ref` is present, the delegate returns-by-ref; otherwise, if *return_type* is `void`, the delegate returns-no-value; otherwise, the delegate returns-by-value. -The optional *parameter_list* specifies the parameters of the delegate. +The optional *parameter_list* specifies the parameters of the delegate. The scope of the parameters of the delegate is `nameof` expressions in attributes placed on the declaration, its type parameters, or its parameters. The *return_type* of a returns-by-value or returns-no-value delegate declaration specifies the type of the result, if any, returned by the delegate. From f1be4ae5c7abfaa1ed099b5a9c01a300109d5c3f Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Fri, 1 May 2026 16:51:52 -0400 Subject: [PATCH 5/5] Add anonymous functions nameof also can be used with anonymous function parameters. --- standard/basic-concepts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/standard/basic-concepts.md b/standard/basic-concepts.md index 856be2fba..100bc06e1 100644 --- a/standard/basic-concepts.md +++ b/standard/basic-concepts.md @@ -697,8 +697,8 @@ The ***scope*** of a name is the region of program text within which it is possi - The scope of a parameter declared in an *indexer_declaration* ([§15.9](classes.md#159-indexers)) is the *indexer_body* of that *indexer_declaration*. - The scope of a parameter declared in an *operator_declaration* ([§15.10](classes.md#1510-operators)) is the *operator_body* of that *operator_declaration*. - The scope of a parameter declared in a *constructor_declaration* ([§15.11](classes.md#1511-instance-constructors)) is the *constructor_initializer* and *block* of that *constructor_declaration*. -- With the exception of discard parameters ([§12.22.2](expressions.md#12222-anonymous-function-signatures)), the scope of a parameter declared in a *lambda_expression* ([§12.22](expressions.md#1222-anonymous-function-expressions)) is the *lambda_expression_body* of that *lambda_expression*. -- With the exception of discard parameters ([§12.22.2](expressions.md#12222-anonymous-function-signatures)), the scope of a parameter declared in an *anonymous_method_expression* ([§12.22](expressions.md#1222-anonymous-function-expressions)) is the *block* of that *anonymous_method_expression*. +- With the exception of discard parameters ([§12.22.2](expressions.md#12222-anonymous-function-signatures)), the scope of a parameter declared in a *lambda_expression* ([§12.22](expressions.md#1222-anonymous-function-expressions)) is the *lambda_expression_body* of that *lambda_expression* and `nameof` expressions in an attribute on the anonymous function or its parameters. +- With the exception of discard parameters ([§12.22.2](expressions.md#12222-anonymous-function-signatures)), the scope of a parameter declared in an *anonymous_method_expression* ([§12.22](expressions.md#1222-anonymous-function-expressions)) is the *block* of that *anonymous_method_expression* and `nameof` expressions in an attribute on the anonymous function or its parameters. - The scope of a label declared in a *labeled_statement* ([§13.5](statements.md#135-labeled-statements)) is the *block* in which the declaration occurs. - The scope of a local variable declared in a *local_variable_declaration* ([§13.6.2](statements.md#1362-local-variable-declarations)) is the *block* in which the declaration occurs. - The scope of a local variable declared in a *switch_block* of a `switch` statement ([§13.8.3](statements.md#1383-the-switch-statement)) is the *switch_block*.