From aee8db5ee0e880fa14c6534924c317edce8e02c8 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 27 Oct 2025 11:27:54 -0400 Subject: [PATCH 01/22] Minor tweaks to V8 before publication --- standard/foreword.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/standard/foreword.md b/standard/foreword.md index fa5feecec..edee198a4 100644 --- a/standard/foreword.md +++ b/standard/foreword.md @@ -1,6 +1,6 @@ # Foreword -This specification replaces ECMA-334:2023. Changes from the previous edition include the addition of the following: +This specification replaces ECMA-334:2023. Changes from the previous edition include the addition of the following features: - enhanced interpolated verbatim strings - asynchronous streams @@ -12,8 +12,9 @@ This specification replaces ECMA-334:2023. Changes from the previous edition inc - `notnull` constraint - null coalescing assignment - nullable reference types +- positional, property, and discard patterns - ranges and indexes - readonly instance members - name shadowing in nested functions - static local functions -- ?? Disposable ref structs +- Disposable ref structs From 8ba769cbc70495cb98de42c0e5bddb04feda6e53 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 27 Oct 2025 11:43:00 -0400 Subject: [PATCH 02/22] Update basic-concepts.md --- standard/basic-concepts.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/standard/basic-concepts.md b/standard/basic-concepts.md index 18d32c4e5..634c6dc95 100644 --- a/standard/basic-concepts.md +++ b/standard/basic-concepts.md @@ -972,7 +972,8 @@ A *namespace_or_type_name* is permitted to reference a static class ([§15.2.2.4 > > interface C : A, B > { -> public void Test() { NestedClass.M(); } // ambiguity between A.NestedClass and B.NestedClass +> public void Test() { NestedClass.M(); } // ambiguity between +> // A.NestedClass and B.NestedClass > } > ``` > From 51c9cd93c50bfdee5bbdafd44a14e9c20d21cc64 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 27 Oct 2025 11:43:26 -0400 Subject: [PATCH 03/22] Fix long-line wrapping From 4ceec3e2b0f66243315f3e88323133c8a5293583 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 27 Oct 2025 11:46:58 -0400 Subject: [PATCH 04/22] Fix long-line wrapping --- standard/types.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/standard/types.md b/standard/types.md index 897df51c4..947fc353a 100644 --- a/standard/types.md +++ b/standard/types.md @@ -947,13 +947,17 @@ Later in the method, the code checks that `s` is not a null reference. The null- > { > int length = s.Length; // No warning. s is not null > -> _ = s == null; // Null check by testing equality. The null state of s is maybe null -> length = s.Length; // Warning, and changes the null state of s to not null +> _ = s == null; // Null check by testing equality. The null state of s +> // is maybe null +> length = s.Length; // Warning, and changes the null state of s +> // to not null > -> _ = s?.Length; // The ?. is a null check and changes the null state of s to maybe null +> _ = s?.Length; // The ?. is a null check and changes the null state of s +> // to maybe null > if (s.Length > 4) // Warning. Changes null state of s to not null > { -> _ = s?[4]; // ?[] is a null check and changes the null state of s to maybe null +> _ = s?[4]; // ?[] is a null check and changes the null state of s +> // to maybe null > _ = s.Length; // Warning. s is maybe null > } > } @@ -1013,7 +1017,8 @@ A compiler can treat a property ([§15.7](classes.md#157-properties)) as either > var t = new Test(); > if (t.DisappearingProperty != null) > { -> int len = t.DisappearingProperty.Length; // No warning. A compiler can assume property is stateful +> int len = t.DisappearingProperty.Length; // No warning. A compiler can +> // assume property is stateful > } > } > } From aa0633ceaccd4e1d2382badfeca66946aa0a2e92 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 27 Oct 2025 11:58:24 -0400 Subject: [PATCH 05/22] Fix long-line wrapping --- standard/expressions.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/standard/expressions.md b/standard/expressions.md index 710c5cea7..774142d9d 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -3117,8 +3117,10 @@ typeof_expression ; unbound_type_name - : identifier generic_dimension_specifier? ('.' identifier generic_dimension_specifier?)* - | unbound_qualified_alias_member ('.' identifier generic_dimension_specifier?)* + : identifier generic_dimension_specifier? + ('.' identifier generic_dimension_specifier?)* + | unbound_qualified_alias_member + ('.' identifier generic_dimension_specifier?)* ; unbound_qualified_alias_member @@ -6654,7 +6656,8 @@ assignment ; assignment_operator - : '=' 'ref'? | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '??=' + : '=' 'ref'? | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | + '<<=' | '??=' | right_shift_assignment ; ``` From 62831fe9458d3e6e1df13ccb20a7dea2474f7660 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 27 Oct 2025 12:00:54 -0400 Subject: [PATCH 06/22] Fix long-line wrapping --- standard/classes.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/standard/classes.md b/standard/classes.md index c2cb4d170..89d89667a 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -515,7 +515,8 @@ Because `notnull` is not a keyword, in *primary_constraint* the not null constra > A x4; > // nonnullable base class requirement allows nonnullable class type argument > B1 x5; -> // possible warning: nonnullable base class requirement prohibits nullable class type argument +> // possible warning: nonnullable base class requirement prohibits nullable +> // class type argument > B1 x6; > // nullable base class requirement allows nonnullable class type argument > B2 x7; From 9715668eb2d86fb8bf75c0cad1bef73469d807b3 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 27 Oct 2025 12:04:00 -0400 Subject: [PATCH 07/22] Fix long-line wrapping --- standard/ranges.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/standard/ranges.md b/standard/ranges.md index 55fdbf2df..e82ed551f 100644 --- a/standard/ranges.md +++ b/standard/ranges.md @@ -243,8 +243,8 @@ A concrete range value is *empty* if `N` is zero. An empty concrete range may ha > > ```csharp > var (ix0, len0) = firstQuad.GetOffsetAndLength(6); // ix0 = 0, len0 = 4 -> var (ix1, len1) = nextQuad.GetOffsetAndLength(6); // throws ArgumentOutOfRangeException -> // as range crosses sequence end +> var (ix1, len1) = nextQuad.GetOffsetAndLength(6); // throws +> // ArgumentOutOfRangeException as range crosses sequence end > var (ix2, len2) = wholeSeq.GetOffsetAndLength(6); // ix2 = 0, len2 = 6 > var (ix3, len3) = dropFirst.GetOffsetAndLength(6); // ix3 = 1, len3 = 5 > var (ix4, len4) = dropLast.GetOffsetAndLength(6); // ix4 = 0, len4 = 5 From 906afa3291355f71ab041e2f4ddb4118cdf936ea Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 27 Oct 2025 12:05:57 -0400 Subject: [PATCH 08/22] Fix long-line wrapping --- standard/attributes.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/standard/attributes.md b/standard/attributes.md index b3cd07a51..85d0e813f 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -958,7 +958,8 @@ Specifies that a given method never returns if the associated `bool` parameter h > { > if (!isNull) > { -> throw new ArgumentException(argumentName, $"argument {argumentName} can't be null"); +> throw new ArgumentException(argumentName, +> $"argument {argumentName} can't be null"); > } > } > @@ -1012,7 +1013,8 @@ Specifies that a nullable value will never be `null` if the method returns (rath > > ```csharp > #nullable enable -> public static void ThrowWhenNull([NotNull] object? value, string valueExpression = "") => +> public static void ThrowWhenNull([NotNull] object? value, +> string valueExpression = "") => > _ = value ?? throw new ArgumentNullException(valueExpression); > > public static void LogMessage(string? message) @@ -1094,7 +1096,8 @@ The iterator won’t have access to the `CancellationToken` argument for `GetAsy > } > } > -> static async IAsyncEnumerable GetStringsAsync([EnumeratorCancellation] CancellationToken token) +> static async IAsyncEnumerable GetStringsAsync( +> [EnumeratorCancellation] CancellationToken token) > { > for (int i = 0; i < 10; i++) > { From df7267b3c16102f7b6e7a39d4d6333bac7ce65b0 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 27 Oct 2025 12:34:42 -0400 Subject: [PATCH 09/22] Tweak term definitions --- standard/arrays.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/arrays.md b/standard/arrays.md index 024417569..f6a6e1b54 100644 --- a/standard/arrays.md +++ b/standard/arrays.md @@ -2,7 +2,7 @@ ## 17.1 General -An array is a data structure that contains a number of variables that are accessed through computed indices. The variables contained in an array, also called the ***elements*** of the array, are all of the same type, and this type is called the ***element type*** of the array. +An array is a data structure that contains a number of variables that are accessed through computed indices. The variables contained in an array are each called an ***element*** of that array. All elements of that array have the same type, and this type is called the ***element type*** of the array. An array has a rank that determines the number of indices associated with each array element. The rank of an array is also referred to as the dimensions of the array. An array with a rank of one is called a ***single-dimensional array***. An array with a rank greater than one is called a ***multi-dimensional array***. Specific sized multi-dimensional arrays are often referred to as two-dimensional arrays, three-dimensional arrays, and so on. Each dimension of an array has an associated length that is an integral number greater than or equal to zero. The dimension lengths are not part of the type of the array, but rather are established when an instance of the array type is created at run-time. The length of a dimension determines the valid range of indices for that dimension: For a dimension of length `N`, indices can range from `0` to `N – 1` inclusive. The total number of elements in an array is the product of the lengths of each dimension in the array. If one or more of the dimensions of an array have a length of zero, the array is said to be empty. From b18a9f4239287b55f113a3cbd38a7bc34a6e73ed Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 27 Oct 2025 12:39:22 -0400 Subject: [PATCH 10/22] Tweak term definitions --- standard/attributes.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/standard/attributes.md b/standard/attributes.md index 85d0e813f..2e9e22c51 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -4,7 +4,7 @@ Much of the C# language enables the programmer to specify declarative information about the entities defined in the program. For example, the accessibility of a method in a class is specified by decorating it with the *method_modifier*s `public`, `protected`, `internal`, and `private`. -C# enables programmers to invent new kinds of declarative information, called ***attributes***. Programmers can then attach attributes to various program entities, and retrieve attribute information in a run-time environment. +C# enables programmers to invent new kinds of declarative information, called ***attribute***s. Programmers can then attach attributes to various program entities, and retrieve attribute information in a run-time environment. > *Note*: For instance, a framework might define a `HelpAttribute` attribute that can be placed on certain program elements (such as classes and methods) to provide a mapping from those program elements to their documentation. *end note* @@ -145,7 +145,7 @@ Attribute classes can have ***positional parameter***s and ***named parameter*** ### 23.2.4 Attribute parameter types -The types of positional and named parameters for an attribute class are limited to the ***attribute parameter types***, which are: +The types of positional and named parameters for an attribute class are limited to the ***attribute parameter type***s, which are: - One of the following types: `bool`, `byte`, `char`, `double`, `float`, `int`, `long`, `sbyte`, `short`, `string`, `uint`, `ulong`, `ushort`. - The type `object`. @@ -156,9 +156,9 @@ The types of positional and named parameters for an attribute class are limited ## 23.3 Attribute specification -***Attribute specification*** is the application of a previously defined attribute to a program entity. An attribute is a piece of additional declarative information that is specified for a program entity. Attributes can be specified at global scope (to specify attributes on the containing assembly or module) and for *type_declaration*s ([§14.7](namespaces.md#147-type-declarations)), *class_member_declaration*s ([§15.3](classes.md#153-class-members)), *interface_member_declaration*s ([§19.4](interfaces.md#194-interface-members)), *struct_member_declaration*s ([§16.3](structs.md#163-struct-members)), *enum_member_declaration*s ([§20.2](enums.md#202-enum-declarations)), *accessor_declaration*s ([§15.7.3](classes.md#1573-accessors)), *event_accessor_declaration*s ([§15.8](classes.md#158-events)), elements of *parameter_list*s ([§15.6.2](classes.md#1562-method-parameters)), and elements of *type_parameter_list*s ([§15.2.3](classes.md#1523-type-parameters)). +Application of a previously defined attribute to a program entity is called ***attribute specification***. An attribute is a piece of additional declarative information that is specified for a program entity. Attributes can be specified at global scope (to specify attributes on the containing assembly or module) and for *type_declaration*s ([§14.7](namespaces.md#147-type-declarations)), *class_member_declaration*s ([§15.3](classes.md#153-class-members)), *interface_member_declaration*s ([§19.4](interfaces.md#194-interface-members)), *struct_member_declaration*s ([§16.3](structs.md#163-struct-members)), *enum_member_declaration*s ([§20.2](enums.md#202-enum-declarations)), *accessor_declaration*s ([§15.7.3](classes.md#1573-accessors)), *event_accessor_declaration*s ([§15.8](classes.md#158-events)), elements of *parameter_list*s ([§15.6.2](classes.md#1562-method-parameters)), and elements of *type_parameter_list*s ([§15.2.3](classes.md#1523-type-parameters)). -Attributes are specified in ***attribute sections***. An attribute section consists of a pair of square brackets, which surround a comma-separated list of one or more attributes. The order in which attributes are specified in such a list, and the order in which sections attached to the same program entity are arranged, is not significant. For instance, the attribute specifications `[A][B]`, `[B][A]`, `[A, B]`, and `[B, A]` are equivalent. +Attributes are specified in ***attribute section***s. An attribute section consists of a pair of square brackets, which surround a comma-separated list of one or more attributes. The order in which attributes are specified in such a list, and the order in which sections attached to the same program entity are arranged, is not significant. For instance, the attribute specifications `[A][B]`, `[B][A]`, `[A, B]`, and `[B, A]` are equivalent. ```ANTLR global_attributes @@ -513,7 +513,7 @@ A class that is decorated with the `AttributeUsage` attribute shall derive from #### 23.5.3.1 General -The attribute `Conditional` enables the definition of ***conditional methods*** and ***conditional attribute classes***. +The attribute `Conditional` enables the definition of ***conditional method***s and ***conditional attribute class***es. #### 23.5.3.2 Conditional methods From e3a50606919251451d78dddeed756860a169560e Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 27 Oct 2025 12:45:39 -0400 Subject: [PATCH 11/22] Tweak term definitions --- standard/basic-concepts.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/standard/basic-concepts.md b/standard/basic-concepts.md index 634c6dc95..dffb917aa 100644 --- a/standard/basic-concepts.md +++ b/standard/basic-concepts.md @@ -39,7 +39,7 @@ The ***effective entry point*** of an application is the entry point declared wi When an application is run, a new ***application domain*** is created. Several different instantiations of an application may exist on the same machine at the same time, and each has its own application domain. An application domain enables application isolation by acting as a container for application state. An application domain acts as a container and boundary for the types defined in the application and the class libraries it uses. Types loaded into one application domain are distinct from the same types loaded into another application domain, and instances of objects are not directly shared between application domains. For instance, each application domain has its own copy of static variables for these types, and a static constructor for a type is run at most once per application domain. Implementations are free to provide implementation-defined policy or mechanisms for the creation and destruction of application domains. -Application startup occurs when the execution environment calls the application’s effective entry point. If the effective entry point declares a parameter, then during application startup, the implementation shall ensure that the initial value of that parameter is a non-null reference to a string array. This array shall consist of non-null references to strings, called ***application parameters***, which are given implementation-defined values by the host environment prior to application startup. The intent is to supply to the application information determined prior to application startup from elsewhere in the hosted environment. +Application startup occurs when the execution environment calls the application’s effective entry point. If the effective entry point declares a parameter, then during application startup, the implementation shall ensure that the initial value of that parameter is a non-null reference to a string array. This array shall consist of non-null references to strings, called ***application parameter***s, which are given implementation-defined values by the host environment prior to application startup. The intent is to supply to the application information determined prior to application startup from elsewhere in the hosted environment. > *Note*: On systems supporting a command line, application parameters correspond to what are generally known as command-line arguments. *end note* @@ -49,7 +49,7 @@ Other than the situations listed above, entry point methods behave like those th ## 7.2 Application termination -***Application termination*** returns control to the execution environment. +The return of control to the execution environment is known as ***application termination***. If the return type of the application’s effective entry point method is `int` and execution completes without resulting in an exception, the value of the `int` returned serves as the application’s ***termination status code***. The purpose of this code is to allow communication of success or failure to the execution environment. If the return type of the effective entry point method is `void` and execution completes without resulting in an exception, the termination status code is `0`. @@ -205,7 +205,7 @@ The textual order in which names are declared is generally of no significance. I ### 7.4.1 General -Namespaces and types have ***members***. +Namespaces and types have ***member***s. > *Note*: The members of an entity are generally available through the use of a qualified name that starts with a reference to the entity, followed by a “`.`” token, followed by the name of the member. *end note* @@ -546,7 +546,7 @@ The following accessibility constraints exist: ## 7.6 Signatures and overloading -Methods, instance constructors, indexers, and operators are characterized by their ***signatures***: +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 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. From ea1e61ffd6e8dc00aca9df71d8b7f795d9c5e518 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 27 Oct 2025 20:18:44 -0400 Subject: [PATCH 12/22] Tweak term definitions --- standard/classes.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/standard/classes.md b/standard/classes.md index 89d89667a..2954cbcba 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -488,7 +488,7 @@ The nullable type annotation, `?`, can only be used on a type parameter that has > > *end example* -The ***not null*** constraint specifies that a type argument used for the type parameter should be a non-nullable value type or a non-nullable reference type. A type argument that isn’t a non-nullable value type or a non-nullable reference type is allowed, but a compiler may produce a diagnostic warning. +The not null constraint specifies that a type argument used for the type parameter should be a non-nullable value type or a non-nullable reference type. A type argument that isn’t a non-nullable value type or a non-nullable reference type is allowed, but a compiler may produce a diagnostic warning. Because `notnull` is not a keyword, in *primary_constraint* the not null constraint is always syntactically ambiguous with *class_type*. For compatibility reasons, if a name lookup ([§12.8.4](expressions.md#1284-simple-names)) of the name `notnull` succeeds it shall be treated as a `class_type`. Otherwise it shall be treated as the not null constraint. @@ -1041,11 +1041,11 @@ A *class_member_declaration* can have any one of the permitted kinds of declared ### 15.3.7 Constituent types -Types that are used in the declaration of a member are called the ***constituent types*** of that member. Possible constituent types are the type of a constant, field, property, event, or indexer, the return type of a method or operator, and the parameter types of a method, indexer, operator, or instance constructor. The constituent types of a member shall be at least as accessible as that member itself ([§7.5.5](basic-concepts.md#755-accessibility-constraints)). +Types that are used in the declaration of a member are called the ***constituent type***s of that member. Possible constituent types are the type of a constant, field, property, event, or indexer, the return type of a method or operator, and the parameter types of a method, indexer, operator, or instance constructor. The constituent types of a member shall be at least as accessible as that member itself ([§7.5.5](basic-concepts.md#755-accessibility-constraints)). ### 15.3.8 Static and instance members -Members of a class are either ***static members*** or ***instance members***. +Members of a class are either ***static member***s or ***instance member***s. > *Note*: Generally speaking, it is useful to think of static members as belonging to classes and instance members as belonging to objects (instances of classes). *end note* @@ -1696,7 +1696,7 @@ A field declaration that declares multiple fields is equivalent to multiple decl ### 15.5.2 Static and instance fields -When a field declaration includes a `static` modifier, the fields introduced by the declaration are ***static fields***. When no `static` modifier is present, the fields introduced by the declaration are ***instance fields***. Static fields and instance fields are two of the several kinds of variables ([§9](variables.md#9-variables)) supported by C#, and at times they are referred to as ***static variables*** and ***instance variables***, respectively. +When a field declaration includes a `static` modifier, the fields introduced by the declaration are ***static field***s. When no `static` modifier is present, the fields introduced by the declaration are ***instance field***s. Static fields and instance fields are two of the several kinds of variables ([§9](variables.md#9-variables)) supported by C#, and at times they are referred to as ***static variable***s and ***instance variable***s, respectively. As explained in [§15.3.8](classes.md#1538-static-and-instance-members), each instance of a class contains a complete set of the instance fields of the class, while there is only one set of static fields for each non-generic class or closed constructed type, regardless of the number of instances of the class or closed constructed type. @@ -1704,7 +1704,7 @@ As explained in [§15.3.8](classes.md#1538-static-and-instance-members), each in #### 15.5.3.1 General -When a *field_declaration* includes a `readonly` modifier, the fields introduced by the declaration are ***readonly fields***. Direct assignments to readonly fields can only occur as part of that declaration or in an instance constructor or static constructor in the same class. (A readonly field can be assigned to multiple times in these contexts.) Specifically, direct assignments to a readonly field are permitted only in the following contexts: +When a *field_declaration* includes a `readonly` modifier, the fields introduced by the declaration are ***readonly field***s. Direct assignments to readonly fields can only occur as part of that declaration or in an instance constructor or static constructor in the same class. (A readonly field can be assigned to multiple times in these contexts.) Specifically, direct assignments to a readonly field are permitted only in the following contexts: - In the *variable_declarator* that introduces the field (by including a *variable_initializer* in the declaration). - For an instance field, in the instance constructors of the class that contains the field declaration, excluding local functions and anonymous functions, and only on the instance being constructed. For a static field, in the static constructor or a static field or property initializer in the class that contains the field declaration, excluding local functions and anonymous functions. These are also the only contexts in which it is valid to pass a readonly field as an output or reference parameter. @@ -1781,7 +1781,7 @@ Constants and readonly fields have different binary versioning semantics. When a ### 15.5.4 Volatile fields -When a *field_declaration* includes a `volatile` modifier, the fields introduced by that declaration are ***volatile fields***. For non-volatile fields, optimization techniques that reorder instructions can lead to unexpected and unpredictable results in multi-threaded programs that access fields without synchronization such as that provided by the *lock_statement* ([§13.13](statements.md#1313-the-lock-statement)). These optimizations can be performed by the compiler, by the run-time system, or by hardware. For volatile fields, such reordering optimizations are restricted: +When a *field_declaration* includes a `volatile` modifier, the fields introduced by that declaration are ***volatile field***s. For non-volatile fields, optimization techniques that reorder instructions can lead to unexpected and unpredictable results in multi-threaded programs that access fields without synchronization such as that provided by the *lock_statement* ([§13.13](statements.md#1313-the-lock-statement)). These optimizations can be performed by the compiler, by the run-time system, or by hardware. For volatile fields, such reordering optimizations are restricted: - A read of a volatile field is called a ***volatile read***. A volatile read has “acquire semantics”; that is, it is guaranteed to occur prior to any references to memory that occur after it in the instruction sequence. - A write of a volatile field is called a ***volatile write***. A volatile write has “release semantics”; that is, it is guaranteed to happen after any memory references prior to the write instruction in the instruction sequence. @@ -4036,7 +4036,7 @@ When a property is declared as an override, any overridden accessors shall be ac ### 15.8.1 General -An ***event*** is a member that enables an object or class to provide notifications. Clients can attach executable code for events by supplying ***event handlers***. +An ***event*** is a member that enables an object or class to provide notifications. Clients can attach executable code for events by supplying ***event handler***s. Events are declared using *event_declaration*s: @@ -5514,7 +5514,7 @@ An asynchronous iterator shall support cancellation of the asynchronous operatio ### 15.15.2 Enumerator interfaces -The ***enumerator interfaces*** are the non-generic interface `System.Collections.IEnumerator` and the generic interface `System.Collections.Generic.IEnumerator`. +The ***enumerator interface***s are the non-generic interface `System.Collections.IEnumerator` and the generic interface `System.Collections.Generic.IEnumerator`. The ***asynchronous enumerator interface*** is the generic interface `System.Collections.Generic.IAsyncEnumerator`. @@ -5522,7 +5522,7 @@ For the sake of brevity, in this subclause and its siblings these interfaces are ### 15.15.3 Enumerable interfaces -The ***enumerable interfaces*** are the non-generic interface `System.Collections.IEnumerable` and the generic interfaces `System.Collections.Generic.IEnumerable`. +The ***enumerable interface***s are the non-generic interface `System.Collections.IEnumerable` and the generic interfaces `System.Collections.Generic.IEnumerable`. The ***asynchronous enumerable interface*** is the generic interface `System.Collections.Generic.IAsyncEnumerable`. From 78fed8dec526be51c34cf944f0606530983c7bb1 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Wed, 29 Oct 2025 07:09:44 -0400 Subject: [PATCH 13/22] Tweak term definitions --- standard/classes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/classes.md b/standard/classes.md index 2954cbcba..5f6820363 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -3292,7 +3292,7 @@ For returns-by-value and returns-by-ref methods the endpoint of the method body ### 15.7.1 General -A ***property*** is a member that provides access to a characteristic of an object or a class. Examples of properties include the length of a string, the size of a font, the caption of a window, and the name of a customer. Properties are a natural extension of fields—both are named members with associated types, and the syntax for accessing fields and properties is the same. However, unlike fields, properties do not denote storage locations. Instead, properties have ***accessors*** that specify the statements to be executed when their values are read or written. Properties thus provide a mechanism for associating actions with the reading and writing of an object or class’s characteristics; furthermore, they permit such characteristics to be computed. +A ***property*** is a member that provides access to a characteristic of an object or a class. Examples of properties include the length of a string, the size of a font, the caption of a window, and the name of a customer. Properties are a natural extension of fields—both are named members with associated types, and the syntax for accessing fields and properties is the same. However, unlike fields, properties do not denote storage locations. Instead, properties have ***accessor***s that specify the statements to be executed when their values are read or written. Properties thus provide a mechanism for associating actions with the reading and writing of an object or class’s characteristics; furthermore, they permit such characteristics to be computed. Properties are declared using *property_declaration*s: From b85e2dcbf30eda419153130700e5f8d85733b5a0 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Wed, 29 Oct 2025 07:15:19 -0400 Subject: [PATCH 14/22] Tweak term definitions --- standard/conversions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/conversions.md b/standard/conversions.md index 0c047927c..b16d7f407 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -726,7 +726,7 @@ A user-defined explicit conversion from a type `S` to a type `T` exists if a u ### 10.6.1 Nullable Conversions -***Nullable conversions*** permit predefined conversions that operate on non-nullable value types to also be used with nullable forms of those types. For each of the predefined implicit or explicit conversions that convert from a non-nullable value type `S` to a non-nullable value type `T` ([§10.2.2](conversions.md#1022-identity-conversion), [§10.2.3](conversions.md#1023-implicit-numeric-conversions), [§10.2.4](conversions.md#1024-implicit-enumeration-conversions), [§10.2.11](conversions.md#10211-implicit-constant-expression-conversions), [§10.3.2](conversions.md#1032-explicit-numeric-conversions) and [§10.3.3](conversions.md#1033-explicit-enumeration-conversions)), the following nullable conversions exist: +A ***nullable conversion*** permits a predefined conversion that operates on a non-nullable value type to also be used with the nullable form of that type. For each of the predefined implicit or explicit conversions that convert from a non-nullable value type `S` to a non-nullable value type `T` ([§10.2.2](conversions.md#1022-identity-conversion), [§10.2.3](conversions.md#1023-implicit-numeric-conversions), [§10.2.4](conversions.md#1024-implicit-enumeration-conversions), [§10.2.11](conversions.md#10211-implicit-constant-expression-conversions), [§10.3.2](conversions.md#1032-explicit-numeric-conversions) and [§10.3.3](conversions.md#1033-explicit-enumeration-conversions)), the following nullable conversions exist: - An implicit or explicit conversion from `S?` to `T?` - An implicit or explicit conversion from `S` to `T?` From 4922dd0387c6f42caed17257b8981fd01a5f0407 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Wed, 29 Oct 2025 07:21:02 -0400 Subject: [PATCH 15/22] Tweak term definitions --- standard/expressions.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/standard/expressions.md b/standard/expressions.md index 774142d9d..083e9fc7a 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -183,7 +183,7 @@ Precedence and associativity can be controlled using parentheses. All unary and binary operators have predefined implementations. In addition, user-defined implementations can be introduced by including operator declarations ([§15.10](classes.md#1510-operators)) in classes and structs. User-defined operator implementations always take precedence over predefined operator implementations: Only when no applicable user-defined operator implementations exist will the predefined operator implementations be considered, as described in [§12.4.4](expressions.md#1244-unary-operator-overload-resolution) and [§12.4.5](expressions.md#1245-binary-operator-overload-resolution). -The ***overloadable unary operators*** are: +The ***overloadable unary operator***s are: > `+ - !` (logical negation only) `~ ++ -- true false` @@ -191,7 +191,7 @@ Only the operators listed above can be overloaded. In particular, it is not poss > *Note*: Although `true` and `false` are not used explicitly in expressions (and therefore are not included in the precedence table in [§12.4.2](expressions.md#1242-operator-precedence-and-associativity)), they are considered operators because they are invoked in several expression contexts: Boolean expressions ([§12.25](expressions.md#1225-boolean-expressions)) and expressions involving the conditional ([§12.19](expressions.md#1219-conditional-operator)) and conditional logical operators ([§12.15](expressions.md#1215-conditional-logical-operators)). *end note* -The ***overloadable binary operators*** are: +The ***overloadable binary operator***s are: > `+ - * / % & | ^ << >> == != > < <= >=` @@ -345,7 +345,7 @@ In both of the above cases, a cast expression can be used to explicitly convert ### 12.4.8 Lifted operators -***Lifted operators*** permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types. Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following: +A ***lifted operator*** permits predefined and user-defined operators that operate on a non-nullable value type to also be used with the nullable form of that type. Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following: - For the unary operators `+`, `++`, `-`, `--`, `!` (logical negation), `^`, and `~`, a lifted form of an operator exists if the operand and result types are both non-nullable value types. The lifted form is constructed by adding a single `?` modifier to the operand and result types. The lifted operator produces a `null` value if the operand is `null`. Otherwise, the lifted operator unwraps the operand, applies the underlying operator, and wraps the result. - For the binary operators `+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `..`, `<<`, and `>>`, a lifted form of an operator exists if the operand and result types are all non-nullable value types. The lifted form is constructed by adding a single `?` modifier to each operand and result type. The lifted operator produces a `null` value if one or both operands are `null` (an exception being the `&` and `|` operators of the `bool?` type, as described in [§12.14.5](expressions.md#12145-nullable-boolean--and--operators)). Otherwise, the lifted operator unwraps the operands, applies the underlying operator, and wraps the result. @@ -6488,7 +6488,7 @@ except when `«v»` is the identifier `«x»`, the translation is #### 12.21.3.8 Transparent identifiers -Certain translations inject range variables with ***transparent identifiers*** denoted by `*`. Transparent identifiers exist only as an intermediate step in the query-expression translation process. +Certain translations inject range variables with ***transparent identifier***s denoted by `*`. Transparent identifiers exist only as an intermediate step in the query-expression translation process. When a query translation injects a transparent identifier, further translation steps propagate the transparent identifier into anonymous functions and anonymous object initializers. In those contexts, transparent identifiers have the following behavior: @@ -6668,12 +6668,12 @@ The `=` operator is called the ***simple assignment operator***. It assigns the The operator `= ref` is called the ***ref assignment operator***. It makes the right operand, which shall be a *variable_reference* ([§9.5](variables.md#95-variable-references)), the referent of the reference variable designated by the left operand. The ref assignment operator is described in [§12.22.3](expressions.md#12223-ref-assignment). -The assignment operators other than the `=` and `= ref` operator are called the ***compound assignment operators***. These operators are processed as follows: +The assignment operators other than the `=` and `= ref` operator are called the ***compound assignment operator***s. These operators are processed as follows: - For the `??=` operator, only if the value of the left-operand is `null`, is the right-operand evaluated and the result assigned to the variable, property, or indexer element given by the left operand. - Otherwise, the indicated operation is performed on the two operands, and then the resulting value is assigned to the variable, property, or indexer element given by the left operand. The compound assignment operators are described in [§12.22.4](expressions.md#12224-compound-assignment). -The `+=` and `-=` operators with an event access expression as the left operand are called the ***event assignment operators***. No other assignment operator is valid with an event access as the left operand. The event assignment operators are described in [§12.22.5](expressions.md#12225-event-assignment). +The `+=` and `-=` operators with an event access expression as the left operand are called the ***event assignment operator***s. No other assignment operator is valid with an event access as the left operand. The event assignment operators are described in [§12.22.5](expressions.md#12225-event-assignment). The assignment operators are right-associative, meaning that operations are grouped from right to left. From dab7a43a2c65d587f3065dfe4d6521a6cdb01df5 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Wed, 29 Oct 2025 07:22:55 -0400 Subject: [PATCH 16/22] Tweak term definitions --- standard/interfaces.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/standard/interfaces.md b/standard/interfaces.md index 5ed62239f..2fef96404 100644 --- a/standard/interfaces.md +++ b/standard/interfaces.md @@ -128,7 +128,7 @@ A type `T` is variance-convertible to a type `T *Example*: In the following code > @@ -793,7 +793,7 @@ The base interfaces of a generic class declaration shall satisfy the uniqueness ### 19.6.2 Explicit interface member implementations -For purposes of implementing interfaces, a class, struct, or interface may declare ***explicit interface member implementations***. An explicit interface member implementation is a method, property, event, or indexer declaration that references a qualified interface member name. A class or struct that implements a non-public member in a base interface must declare an explicit interface member implementation. An interface that implements a member in a base interface must declare an explicit interface member implementation. +For purposes of implementing interfaces, a class, struct, or interface may declare ***explicit interface member implementation***s. An explicit interface member implementation is a method, property, event, or indexer declaration that references a qualified interface member name. A class or struct that implements a non-public member in a base interface must declare an explicit interface member implementation. An interface that implements a member in a base interface must declare an explicit interface member implementation. A derived interface member that satisfies interface mapping ([§19.6.5](interfaces.md#1965-interface-mapping)) hides the base interface member ([§7.7.2](basic-concepts.md#772-name-hiding)). The compiler shall issue a warning unless the `new` modifier is present. From 44cc81e19abf3f19ca2cc9cf070d149df3c9391a Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Wed, 29 Oct 2025 07:25:44 -0400 Subject: [PATCH 17/22] Tweak term definitions --- standard/lexical-structure.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/standard/lexical-structure.md b/standard/lexical-structure.md index 7f9ac6ddd..f47d30a4e 100644 --- a/standard/lexical-structure.md +++ b/standard/lexical-structure.md @@ -2,7 +2,7 @@ ## 6.1 Programs -A C# ***program*** consists of one or more source files, known formally as ***compilation units*** ([§14.2](namespaces.md#142-compilation-units)). Although a compilation unit might have a one-to-one correspondence with a file in a file system, such correspondence is not required. +A C# ***program*** consists of one or more source files, each known formally as a ***compilation unit*** ([§14.2](namespaces.md#142-compilation-units)). Although a compilation unit might have a one-to-one correspondence with a file in a file system, such correspondence is not required. Conceptually speaking, a program is compiled using three steps: @@ -343,7 +343,7 @@ Whitespace ### 6.4.1 General -There are several kinds of ***tokens***: identifiers, keywords, literals, operators, and punctuators. White space and comments are not tokens, though they act as separators for tokens. +There are several kinds of ***token***s: identifiers, keywords, literals, operators, and punctuators. White space and comments are not tokens, though they act as separators for tokens. ```ANTLR token @@ -887,7 +887,7 @@ The type of a *Character_Literal* is `char`. #### 6.4.5.6 String literals -C# supports two forms of string literals: ***regular string literals*** and ***verbatim string literals***. A regular string literal consists of zero or more characters enclosed in double quotes, as in `"hello"`, and can include both simple escape sequences (such as `\t` for the tab character), and hexadecimal and Unicode escape sequences. +C# supports two forms of string literals: ***regular string literal***s and ***verbatim string literal***s. A regular string literal consists of zero or more characters enclosed in double quotes, as in `"hello"`, and can include both simple escape sequences (such as `\t` for the tab character), and hexadecimal and Unicode escape sequences. A verbatim string literal consists of an `@` character followed by a double-quote character, zero or more characters, and a closing double-quote character. @@ -1306,7 +1306,7 @@ fragment PP_Endif ; ``` -Conditional compilation directives shall be written in groups consisting of, in order, a `#if` directive, zero or more `#elif` directives, zero or one `#else` directive, and a `#endif` directive. Between the directives are ***conditional sections*** of source code. Each section is controlled by the immediately preceding directive. A conditional section may itself contain nested conditional compilation directives provided these directives form complete groups. +Conditional compilation directives shall be written in groups consisting of, in order, a `#if` directive, zero or more `#elif` directives, zero or one `#else` directive, and a `#endif` directive. Between the directives are ***conditional section***s of source code. Each section is controlled by the immediately preceding directive. A conditional section may itself contain nested conditional compilation directives provided these directives form complete groups. At most one of the contained conditional sections is selected for normal lexical processing: From f1d6d90a5287a98f03d1cb7009ef48c1749460f7 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Wed, 29 Oct 2025 07:27:54 -0400 Subject: [PATCH 18/22] Tweak term definitions --- standard/namespaces.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/namespaces.md b/standard/namespaces.md index 286bdf53d..51cfad6ec 100644 --- a/standard/namespaces.md +++ b/standard/namespaces.md @@ -159,7 +159,7 @@ An error occurs if a program declares an extern alias for which no external defi ### 14.5.1 General -***Using directives*** facilitate the use of namespaces and types defined in other namespaces. Using directives impact the name resolution process of *namespace_or_type_name*s ([§7.8](basic-concepts.md#78-namespace-and-type-names)) and *simple_name*s ([§12.8.4](expressions.md#1284-simple-names)), but unlike declarations, *using_directive*s do not contribute new members to the underlying declaration spaces of the compilation units or namespaces within which they are used. +A ***using directive*** facilitates the use of namespaces and types defined in other namespaces. Using directives impact the name resolution process of *namespace_or_type_name*s ([§7.8](basic-concepts.md#78-namespace-and-type-names)) and *simple_name*s ([§12.8.4](expressions.md#1284-simple-names)), but unlike declarations, *using_directive*s do not contribute new members to the underlying declaration spaces of the compilation units or namespaces within which they are used. ```ANTLR using_directive From db1be65452db6f4c2c4d4e65bbd6446a8ffeff30 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Wed, 29 Oct 2025 07:42:57 -0400 Subject: [PATCH 19/22] Tweak term definitions --- standard/types.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/standard/types.md b/standard/types.md index 947fc353a..1db30f80b 100644 --- a/standard/types.md +++ b/standard/types.md @@ -2,7 +2,7 @@ ## 8.1 General -The types of the C# language are divided into two main categories: ***reference types*** and ***value types***. Both value types and reference types may be ***generic types***, which take one or more ***type parameters***. Type parameters can designate both value types and reference types. +The types of the C# language are divided into two main categories: ***reference type*** and ***value type***. A value type or a reference type may be a ***generic type***, which takes one or more ***type parameter***s. Type parameters can designate both value types and reference types. ```ANTLR type @@ -15,7 +15,7 @@ type *pointer_type* ([§24.3](unsafe-code.md#243-pointer-types)) is available only in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). -Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store ***references*** to their data, the latter being known as ***objects***. With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. +Value types differ from reference types in that a variable of a value types directly contains its data, whereas a variable of a reference type stores a ***reference*** to its data, the latter being known as an ***object***. With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. > *Note*: When a variable is a reference or output parameter, it does not have its own storage but references the storage of another variable. In this case, the ref or out variable is effectively an alias for another variable and not a distinct variable. *end note* @@ -91,7 +91,7 @@ A reference type value is a reference to an ***instance*** of the type, the latt ### 8.2.2 Class types -A class type defines a data structure that contains ***data members*** (constants and fields), ***function members*** (methods, properties, events, indexers, operators, instance constructors, finalizers, and static constructors), and nested types. Class types support inheritance, a mechanism whereby derived classes can extend and specialize base classes. Instances of class types are created using *object_creation_expression*s ([§12.8.17.2](expressions.md#128172-object-creation-expressions)). +A class type defines a data structure that contains ***data member***s (constants and fields), ***function member***s (methods, properties, events, indexers, operators, instance constructors, finalizers, and static constructors), and nested types. Class types support inheritance, a mechanism whereby derived classes can extend and specialize base classes. Instances of class types are created using *object_creation_expression*s ([§12.8.17.2](expressions.md#128172-object-creation-expressions)). Class types are described in [§15](classes.md#15-classes). @@ -151,7 +151,7 @@ Delegate types are described in [§21](delegates.md#21-delegates). ### 8.3.1 General -A value type is either a struct type or an enumeration type. C# provides a set of predefined struct types called the ***simple types***. The simple types are identified through keywords. +A value type is either a struct type or an enumeration type. C# provides a set of predefined struct types called the ***simple type***s. The simple types are identified through keywords. ```ANTLR value_type @@ -403,7 +403,7 @@ An enumeration type is a distinct type with named constants. Every enumeration t ### 8.3.11 Tuple types -A tuple type represents an ordered, fixed-length sequence of values with optional names and individual types. The number of elements in a tuple type is referred to as its ***arity***. A tuple type is written `(T1 I1, ..., Tn In)` with n ≥ 2, where the identifiers `I1...In` are optional ***tuple element names***. +A tuple type represents an ordered, fixed-length sequence of values with optional names and individual types. The number of elements in a tuple type is referred to as its ***arity***. A tuple type is written `(T1 I1, ..., Tn In)` with n ≥ 2, where the identifiers `I1...In` are optional ***tuple element name***s. This syntax is shorthand for a type constructed with the types `T1...Tn` from `System.ValueTuple<...>`, which shall be a set of generic struct types capable of directly expressing tuple types of any arity between two and seven inclusive. There does not need to exist a `System.ValueTuple<...>` declaration that directly matches the arity of any tuple type with a corresponding number of type parameters. Instead, tuples with an arity greater than seven are represented with a generic struct type `System.ValueTuple` that in addition to tuple elements has a `Rest` field containing a nested value of the remaining elements, using another `System.ValueTuple<...>` type. Such nesting may be observable in various ways, e.g. via the presence of a `Rest` field. Where only a single additional field is required, the generic struct type `System.ValueTuple` is used; this type is not considered a tuple type in itself. Where more than seven additional fields are required, `System.ValueTuple` is used recursively. @@ -480,7 +480,7 @@ Boxing is described in more detail in [§10.2.9](conversions.md#1029-boxing-conv ### 8.4.1 General -A generic type declaration, by itself, denotes an ***unbound generic type*** that is used as a “blueprint” to form many different types, by way of applying ***type arguments***. The type arguments are written within angle brackets (`<` and `>`) immediately following the name of the generic type. A type that includes at least one type argument is called a ***constructed type***. A constructed type can be used in most places in the language in which a type name can appear. An unbound generic type can only be used within a *typeof_expression* ([§12.8.18](expressions.md#12818-the-typeof-operator)). +A generic type declaration, by itself, denotes an ***unbound generic type*** that is used as a “blueprint” to form many different types, by way of applying ***type argument***s. The type arguments are written within angle brackets (`<` and `>`) immediately following the name of the generic type. A type that includes at least one type argument is called a ***constructed type***. A constructed type can be used in most places in the language in which a type name can appear. An unbound generic type can only be used within a *typeof_expression* ([§12.8.18](expressions.md#12818-the-typeof-operator)). Constructed types can also be used in expressions as simple names ([§12.8.4](expressions.md#1284-simple-names)) or when accessing a member ([§12.8.7](expressions.md#1287-member-access)). @@ -547,7 +547,7 @@ Each type argument shall satisfy any constraints on the corresponding type param ### 8.4.3 Open and closed types -All types can be classified as either ***open types*** or ***closed types***. An open type is a type that involves type parameters. More specifically: +Any type can be classified as either an ***open type*** or a ***closed type***. An open type is a type that involves type parameters. More specifically: - A type parameter defines an open type. - An array type is an open type if and only if its element type is an open type. @@ -633,7 +633,7 @@ As a type, type parameters are purely a compile-time construct. At run-time, eac ## 8.6 Expression tree types -***Expression trees*** permit lambda expressions to be represented as data structures instead of executable code. Expression trees are values of ***expression tree types*** of the form `System.Linq.Expressions.Expression`, where `TDelegate` is any delegate type. For the remainder of this specification these types will be referred to using the shorthand `Expression`. +An ***expression tree*** permits a lambda expression to be represented as a data structure instead of executable code. An expression trees is a value of ***expression tree type*** of the form `System.Linq.Expressions.Expression`, where `TDelegate` is any delegate type. For the remainder of this specification these types will be referred to using the shorthand `Expression`. If a conversion exists from a lambda expression to a delegate type `D`, a conversion also exists to the expression tree type `Expression`. Whereas the conversion of a lambda expression to a delegate type generates a delegate that references executable code for the lambda expression, conversion to an expression tree type creates an expression tree representation of the lambda expression. More details of this conversion are provided in [§10.7.3](conversions.md#1073-evaluation-of-lambda-expression-conversions-to-expression-tree-types). @@ -1168,4 +1168,4 @@ A compiler may issue a warning when nullability differs in either direction in t > > *end example* -***End of conditionally normative text*** +**End of conditionally normative text** From 231108479562928bc971b293ab63fe8b7f48bc0e Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Wed, 29 Oct 2025 07:44:32 -0400 Subject: [PATCH 20/22] Tweak term definitions --- standard/unsafe-code.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/unsafe-code.md b/standard/unsafe-code.md index 9d6825717..991eab491 100644 --- a/standard/unsafe-code.md +++ b/standard/unsafe-code.md @@ -253,7 +253,7 @@ In an unsafe context, several constructs are available for operating on pointers ## 24.4 Fixed and moveable variables -The address-of operator ([§24.6.5](unsafe-code.md#2465-the-address-of-operator)) and the `fixed` statement ([§24.7](unsafe-code.md#247-the-fixed-statement)) divide variables into two categories: ***Fixed variables*** and ***moveable variables***. +The address-of operator ([§24.6.5](unsafe-code.md#2465-the-address-of-operator)) and the `fixed` statement ([§24.7](unsafe-code.md#247-the-fixed-statement)) divide variables into two categories: ***Fixed variable***s and ***moveable variable***s. Fixed variables reside in storage locations that are unaffected by operation of the garbage collector. (Examples of fixed variables include local variables, value parameters, and variables created by dereferencing pointers.) On the other hand, moveable variables reside in storage locations that are subject to relocation or disposal by the garbage collector. (Examples of moveable variables include fields in objects and elements of arrays.) From bbf7233c3b556eac6bad150015419b07ae0166b5 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Wed, 29 Oct 2025 07:52:07 -0400 Subject: [PATCH 21/22] fix formatting --- standard/basic-concepts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/basic-concepts.md b/standard/basic-concepts.md index dffb917aa..d50615ac0 100644 --- a/standard/basic-concepts.md +++ b/standard/basic-concepts.md @@ -49,7 +49,7 @@ Other than the situations listed above, entry point methods behave like those th ## 7.2 Application termination -The return of control to the execution environment is known as ***application termination***. +The return of control to the execution environment is known as ***application termination***. If the return type of the application’s effective entry point method is `int` and execution completes without resulting in an exception, the value of the `int` returned serves as the application’s ***termination status code***. The purpose of this code is to allow communication of success or failure to the execution environment. If the return type of the effective entry point method is `void` and execution completes without resulting in an exception, the termination status code is `0`. From 714e07daaea71ae0ca96c58c3e44bbdefe0c24bd Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Fri, 31 Oct 2025 12:08:24 -0400 Subject: [PATCH 22/22] correct link --- standard/expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/expressions.md b/standard/expressions.md index beffaa1aa..ac41d3c79 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -6749,7 +6749,7 @@ The assignment operators other than the `=` and `= ref` operator are called the - For the `??=` operator, only if the value of the left-operand is `null`, is the right-operand evaluated and the result assigned to the variable, property, or indexer element given by the left operand. - Otherwise, the indicated operation is performed on the two operands, and then the resulting value is assigned to the variable, property, or indexer element given by the left operand. The compound assignment operators are described in [§12.23.4](expressions.md#12234-compound-assignment). -The `+=` and `-=` operators with an event access expression as the left operand are called the ***event assignment operator***s. No other assignment operator is valid with an event access as the left operand. The event assignment operators are described in [§12.22.5](expressions.md#12225-event-assignment). +The `+=` and `-=` operators with an event access expression as the left operand are called the ***event assignment operator***s. No other assignment operator is valid with an event access as the left operand. The event assignment operators are described in [§12.23.5](expressions.md#12235-event-assignment). The assignment operators are right-associative, meaning that operations are grouped from right to left.