diff --git a/standard/classes.md b/standard/classes.md index 28a5724d4..ab464885d 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -2793,9 +2793,9 @@ A compile-time error occurs unless all of the following are true for an override - The override method has a return type that is convertible by an identity conversion or (if the method has a value return) an implicit reference conversion to the return type of the overridden base method. - The override method has a return type that is convertible by an identity conversion or (if the method has a value return) an implicit reference conversion to the return type of every override of the overridden base method that is declared in a (direct or indirect) base type of the override method. - The override declaration and the overridden base method have the same declared accessibility. In other words, an override declaration cannot change the accessibility of the virtual method. However, if the overridden base method is protected internal and it is declared in a different assembly than the assembly containing the override declaration then the override declaration’s declared accessibility shall be protected. -- The override method's return type is at least as accessible as the override method. +- The override method’s return type is at least as accessible as the override method. > *Note*: This constraint permits an override method in a `private` class to have a `private` return type. However, it requires a `public` override method in a `public` type to have a `public` return type. *end note* -- A *type_parameter_constraints_clause* may only consist of the `class`, `struct`, or `default` *primary_constraint*s. The `class` and `struct` constraints may be placed on *type_parameter*s known according to the inherited constraints to be either reference or non-nullable value types respectively. The `default` constraint may be placed on *type_parameter*s that are not constrained to either reference or value types. Any type of the form `T?` in the overriding method's signature, where `T` is a type parameter, is interpreted as follows: +- A *type_parameter_constraints_clause* may only consist of the `class`, `struct`, or `default` *primary_constraint*s. The `class` and `struct` constraints may be placed on *type_parameter*s known according to the inherited constraints to be either reference or non-nullable value types respectively. The `default` constraint may be placed on *type_parameter*s that are not constrained to either reference or value types. Any type of the form `T?` in the overriding method’s signature, where `T` is a type parameter, is interpreted as follows: - If a `class` constraint is added for type parameter `T` then `T?` is a nullable reference type. - If either a `struct` constraint is added, or no constraint is added and the inherited constraint is a value type constraint, for the type parameter `T` then `T?` is a nullable value type. - If a `default` constraint is added for type parameter `T`, the interpretation of `T?` depends on the type argument substituted for `T`: @@ -4279,9 +4279,9 @@ Abstract property declarations are only permitted in abstract classes ([§15.2.2 For an override property `P` declared in an interface `I`, the overridden base property is determined by examining each direct or indirect base interface of `I`, collecting the set of interfaces declaring an accessible property which has the same name as `P`. If this set of interfaces has a *most derived type*, to which there is an identity or implicit reference conversion from every type in this set, and that type contains a unique such property declaration, then that is the overridden base property. -The override declaration and the overridden base property are required to have the same declared accessibility. In other words, an override declaration shall not change the accessibility of the base property. However, if the overridden base property is protected internal and it is declared in a different assembly than the assembly containing the override declaration then the override declaration’s declared accessibility shall be protected. The overriding property's type shall be at least as accessible as the overriding property. If the inherited property has only a single accessor (i.e., if the inherited property is read-only, init-only, or write-only), the overriding property shall include only that accessor. If the inherited property includes two accessors (i.e., if the inherited property is read-write or read-init), the overriding property can include either a single accessor or both accessors. There shall be an identity conversion or (if the inherited property is read-only and has a value return) an implicit reference conversion between the type of the overriding and the inherited property. For an override property declared in an interface, there shall also be an identity conversion or (if the inherited property is read-only and has a value return) an implicit reference conversion between the type of the overriding property and the type of every override of the overridden base property that is declared in a (direct or indirect) base interface of the overriding property. +The override declaration and the overridden base property are required to have the same declared accessibility. In other words, an override declaration shall not change the accessibility of the base property. However, if the overridden base property is protected internal and it is declared in a different assembly than the assembly containing the override declaration then the override declaration’s declared accessibility shall be protected. The overriding property’s type shall be at least as accessible as the overriding property. If the inherited property has only a single accessor (i.e., if the inherited property is read-only, init-only, or write-only), the overriding property shall include only that accessor. If the inherited property includes two accessors (i.e., if the inherited property is read-write or read-init), the overriding property can include either a single accessor or both accessors. There shall be an identity conversion or (if the inherited property is read-only and has a value return) an implicit reference conversion between the type of the overriding and the inherited property. For an override property declared in an interface, there shall also be an identity conversion or (if the inherited property is read-only and has a value return) an implicit reference conversion between the type of the overriding property and the type of every override of the overridden base property that is declared in a (direct or indirect) base interface of the overriding property. -> *Note*: The accessibility constraint on the overriding property's type permits an override property in a `private` class to have a `private` property type. However, it requires a `public` override property in a `public` type to have a `public` property type. *end note* +> *Note*: The accessibility constraint on the overriding property’s type permits an override property in a `private` class to have a `private` property type. However, it requires a `public` override property in a `public` type to have a `public` property type. *end note* An overriding property declaration may include the `sealed` modifier. Use of this modifier prevents a derived class or interface from further overriding the property. The accessors of a sealed property are also sealed. @@ -5879,15 +5879,15 @@ The ability to provide an alternate builder type shall not be used when the synt When an async function is compiled, the builder type is determined by: 1. Using the builder type from `AsyncMethodBuilderAttribute`, if one is present; -1. Otherwise, falling back to the builder type determined by the async function's *return_type* ([§15.14.2](classes.md#15142-task-type-builder-pattern)). +1. Otherwise, falling back to the builder type determined by the async function’s *return_type* ([§15.14.2](classes.md#15142-task-type-builder-pattern)). If an `AsyncMethodBuilderAttribute` is present, the builder type specified by that attribute is constructed, if necessary. -If the override type is an open generic type, take the single type argument of the async function's return type and substitute it into the override type. +If the override type is an open generic type, take the single type argument of the async function’s return type and substitute it into the override type. If the override type is a bound generic type, then an error results. -If the async function's return type does not have a single type argument, an error results. +If the async function’s return type does not have a single type argument, an error results. To verify that the builder type is compatible with *return_type* of the async function: @@ -6198,7 +6198,7 @@ If a record class is derived directly from `object`, the record class type has a System.Type EqualityContract { get; }; ``` -The property is `private` if the record class type is `sealed`. Otherwise, the property is `virtual` and `protected`. The property may be declared explicitly. It is an error if the explicit declaration does not match the expected signature or accessibility, or if the explicit declaration doesn't allow overriding in a derived type and the record class type is not `sealed`. +The property is `private` if the record class type is `sealed`. Otherwise, the property is `virtual` and `protected`. The property may be declared explicitly. It is an error if the explicit declaration does not match the expected signature or accessibility, or if the explicit declaration doesn’t allow overriding in a derived type and the record class type is not `sealed`. If the record class type is derived from some base record class type `Base`, the record class type includes a provided property declared as follows: @@ -6206,9 +6206,9 @@ If the record class type is derived from some base record class type `Base`, the protected override System.Type EqualityContract { get; }; ``` -The property may be declared explicitly. It is an error if the explicit declaration does not match the expected signature or accessibility, or if the explicit declaration doesn't allow overriding in a derived type and the record class type is not `sealed`. It is an error if either the provided or the explicitly declared property doesn't override a property with this signature in the record class type `Base` (for example, if the property is missing in the `Base`, or is sealed, or is not virtual). The provided property returns `typeof(R)` where `R` is the record class type. +The property may be declared explicitly. It is an error if the explicit declaration does not match the expected signature or accessibility, or if the explicit declaration doesn’t allow overriding in a derived type and the record class type is not `sealed`. It is an error if either the provided or the explicitly declared property doesn’t override a property with this signature in the record class type `Base` (for example, if the property is missing in the `Base`, or is sealed, or is not virtual). The provided property returns `typeof(R)` where `R` is the record class type. -The record class type implements `System.IEquatable` and includes a provided, strongly-typed overload of `Equals(R? other)` where `R` is the record class type. The method is `public`, and the method is `virtual` unless the record class type is `sealed`. The method can be declared explicitly. It is an error if the explicit declaration does not match the expected signature or accessibility, or the explicit declaration doesn't allow overriding in a derived type and the record class type is not `sealed`. +The record class type implements `System.IEquatable` and includes a provided, strongly-typed overload of `Equals(R? other)` where `R` is the record class type. The method is `public`, and the method is `virtual` unless the record class type is `sealed`. The method can be declared explicitly. It is an error if the explicit declaration does not match the expected signature or accessibility, or the explicit declaration doesn’t allow overriding in a derived type and the record class type is not `sealed`. If `Equals(R? other)` is user-defined but `GetHashCode` is not, a warning shall be issued. @@ -6238,7 +6238,7 @@ If the record class type is derived from some base record class type, `Base`, th public sealed override bool Equals(Base? other); ``` -It is an error if the override is declared explicitly. It is an error if the method doesn't override a method with the same signature in record class type `Base` (for example, if the method is missing in the `Base`, or is sealed, or is not virtual). The provided override returns `Equals((object?)other)`. +It is an error if the override is declared explicitly. It is an error if the method doesn’t override a method with the same signature in record class type `Base` (for example, if the method is missing in the `Base`, or is sealed, or is not virtual). The provided override returns `Equals((object?)other)`. The record class type includes a provided override declared as follows: @@ -6246,7 +6246,7 @@ The record class type includes a provided override declared as follows: public override bool Equals(object? obj); ``` -It is an error if the override is declared explicitly. It is an error if the method doesn't override `object.Equals(object? obj)` (for example, due to shadowing in intermediate base types). The provided override returns `Equals(other as R)` where `R` is the record class type. +It is an error if the override is declared explicitly. It is an error if the method doesn’t override `object.Equals(object? obj)` (for example, due to shadowing in intermediate base types). The provided override returns `Equals(other as R)` where `R` is the record class type. The record class type includes a provided override method declared as follows: @@ -6254,7 +6254,7 @@ The record class type includes a provided override method declared as follows: public override int GetHashCode(); ``` -The method may be declared explicitly. It is an error if the explicit declaration doesn't allow overriding it in a derived type and the record class type is not `sealed`. It is an error if either the provided, or the explicitly declared, method doesn't override `object.GetHashCode()` (for example, due to shadowing in intermediate base types). +The method may be declared explicitly. It is an error if the explicit declaration doesn’t allow overriding it in a derived type and the record class type is not `sealed`. It is an error if either the provided, or the explicitly declared, method doesn’t override `object.GetHashCode()` (for example, due to shadowing in intermediate base types). A warning shall be issued if one of `Equals(R?)` and `GetHashCode()` is explicitly declared, but the other is not. @@ -6364,7 +6364,7 @@ A record class type contains two copying members: - A copy constructor ([§15.16.6.2](classes.md#151662-copy-constructors)) - A provided public, parameter-less, instance clone method having an unspecified reserved name -The copy constructor shall not execute any instance field/property initializers present in the record class declaration. If the constructor is not explicitly declared, it shall be provided by the implementation. If the provided record class is sealed, the constructor shall be private; otherwise; it shall be protected. An explicitly declared copy constructor shall be either public or protected, unless the record class is sealed. The first thing the constructor shall do, is to call a copy constructor of the base class, or a parameter-less `object` constructor if the record inherits from `object`. It is an error for a user-defined copy constructor to use an implicit or explicit *constructor_initializer* that doesn't fulfill this requirement. After a base copy constructor is invoked, a provided copy constructor shall copy values for all instance fields implicitly or explicitly declared within the record class type. The sole presence of a copy constructor, whether explicit or implicit, shall not prevent an automatic addition of a default instance constructor. +The copy constructor shall not execute any instance field/property initializers present in the record class declaration. If the constructor is not explicitly declared, it shall be provided by the implementation. If the provided record class is sealed, the constructor shall be private; otherwise; it shall be protected. An explicitly declared copy constructor shall be either public or protected, unless the record class is sealed. The first thing the constructor shall do, is to call a copy constructor of the base class, or a parameter-less `object` constructor if the record inherits from `object`. It is an error for a user-defined copy constructor to use an implicit or explicit *constructor_initializer* that doesn’t fulfill this requirement. After a base copy constructor is invoked, a provided copy constructor shall copy values for all instance fields implicitly or explicitly declared within the record class type. The sole presence of a copy constructor, whether explicit or implicit, shall not prevent an automatic addition of a default instance constructor. If a virtual clone method is present in the base record class, the provided clone method shall override it, and the return type of the clone method shall be the current containing type if the covariant-returns feature is supported, and the override return type otherwise. It is an error if the base record class clone method is sealed. If a virtual clone method is not present in the base record class, the return type of the clone method shall be the containing type and the method shall be virtual, unless the record class is sealed or abstract. If the containing record class is abstract, the provided clone method shall also be abstract. If the clone method is not abstract, it shall return the result of a call to a copy constructor. @@ -6383,7 +6383,7 @@ The ***printable members of a class*** are the instance public field and readabl The method performs the following tasks: 1. Calls the method `System.Runtime.CompilerServices.RuntimeHelpers.EnsureSufficientExecutionStack()` if that method is present and the record class has printable members. -2. For each of the record class's printable members, appends that member’s name followed by space `=`space, followed by the member's value separated with `,` and a space. +2. For each of the record class’s printable members, appends that member’s name followed by space `=`space, followed by the member’s value separated with `,` and a space. 3. Returns `true` if the record class has printable members; otherwise, `false`. For a member that has a value type, its value is converted to a string representation. @@ -6401,7 +6401,7 @@ If the record class has no printable members, the method shall call the base `Pr 3. For each of the record class’s printable members, appends that member’s name followed by space `=` space, followed by the member’s value: `this.member` (or `this.member.ToString()` for value types), separated with `,` and space, 4. Returns `true`. -The `PrintMembers` method may be declared explicitly. It is an error if the explicit declaration does not match the expected signature or accessibility, or if the explicit declaration doesn't allow overriding it in a derived type and the record class type is not sealed. +The `PrintMembers` method may be declared explicitly. It is an error if the explicit declaration does not match the expected signature or accessibility, or if the explicit declaration doesn’t allow overriding it in a derived type and the record class type is not sealed. The record class shall include a provided method method declared as follows: @@ -6409,7 +6409,7 @@ The record class shall include a provided method method declared as follows: public override string ToString(); ``` -The method may be declared explicitly. It is an error if the explicit declaration does not match the expected signature or accessibility, or if the explicit declaration doesn't allow overriding it in a derived type and the record class type is not sealed. It is an error if either the provided or explicitly declared method doesn't override `object.ToString()` (for example, due to shadowing in intermediate base types). +The method may be declared explicitly. It is an error if the explicit declaration does not match the expected signature or accessibility, or if the explicit declaration doesn’t allow overriding it in a derived type and the record class type is not sealed. It is an error if either the provided or explicitly declared method doesn’t override `object.ToString()` (for example, due to shadowing in intermediate base types). Sealing an explicitly declared `ToString` method prevents the compiler from providing a `ToString` method for any derived record types. However, this does not prevent the compiler from providing `PrintMembers`. @@ -6419,7 +6419,7 @@ The provided method: 1. Appends the record class name to the builder, followed by ` { `, 1. Invokes the record class’s `PrintMembers` method giving it the builder, followed by a space if it returned `true`, 1. Appends `}`, -1. Returns the builder's contents with `builder.ToString()`. +1. Returns the builder’s contents with `builder.ToString()`. > *Example*: Given the following: > diff --git a/standard/conversions.md b/standard/conversions.md index bc1a0dc2d..44b18b8d8 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -149,7 +149,7 @@ An implicit enumeration conversion permits a *constant_expression* ([§12.26](ex An implicit interpolated string conversion permits an *interpolated_string_expression* ([§12.8.3](expressions.md#1283-interpolated-string-expressions)) to be converted to `System.IFormattable` or `System.FormattableString` (which implements `System.IFormattable`). When this conversion is applied, a string value is not composed from the interpolated string. Instead an instance of `System.FormattableString` is created, as further described in [§12.8.3](expressions.md#1283-interpolated-string-expressions). -For any type `T` that is an applicable interpolated string handler type ([§23.5.9.1.1](attributes.md#235911-declaring-a-custom-handler)), there exists an implicit interpolated string handler conversion to `T` from a non-constant *ISE* ([§12.8.3](expressions.md#1283-interpolated-string-expressions)). This conversion exists, regardless of whether errors are found later when attempting to lower the interpolation using the handler pattern. This ensures that there are predictable and useful errors, and that runtime behavior doesn't change based on the content of an interpolated string. +For any type `T` that is an applicable interpolated string handler type ([§23.5.9.1.1](attributes.md#235911-declaring-a-custom-handler)), there exists an implicit interpolated string handler conversion to `T` from a non-constant *ISE* ([§12.8.3](expressions.md#1283-interpolated-string-expressions)). This conversion exists, regardless of whether errors are found later when attempting to lower the interpolation using the handler pattern. This ensures that there are predictable and useful errors, and that runtime behavior doesn’t change based on the content of an interpolated string. ### 10.2.6 Implicit nullable conversions @@ -406,7 +406,7 @@ There is an implicit conversion from a *switch_expression* ([§12.12](expression There is an implicit ***object-creation conversion*** from a *target_typed_new* expression ([§12.8.17.2](expressions.md#128172-object-creation-expressions)) to every type. -Given a target type `T`, if `T` is an instance of `System.Nullable`, the type `T0` is `T`'s underlying type. Otherwise `T0` is `T`. The meaning of a *target_typed_new* expression that is converted to the type `T` is the same as the meaning of a corresponding *object_creation_expression* that specifies `T0` as the type. +Given a target type `T`, if `T` is an instance of `System.Nullable`, the type `T0` is `T`’s underlying type. Otherwise `T0` is `T`. The meaning of a *target_typed_new* expression that is converted to the type `T` is the same as the meaning of a corresponding *object_creation_expression* that specifies `T0` as the type. ### 10.2.20 Implicit conditional expression conversions diff --git a/standard/expressions.md b/standard/expressions.md index 9fc20e336..1ffb7699a 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -1632,7 +1632,7 @@ A *constant interpolated string* is an *interpolated_string_expression* that con - no interpolations, or - interpolations whose *expression*s are constant expressions of type `string`, and these interpolations have no *interpolation_minimum_width*, *Regular_Interpolation_Format*, or *Verbatim_Interpolation_Format* specifiers. -For example, $"Hello", $"{cs1}, world!" (given `const string cs1 = $"Hello";`), $"{"Hello," + $"world!"}", and $"xxx{(true ? $"{"X"}" : $"{$"{"Y"}"}")}yyy" are all constant interpolated strings. However, $"{123}" and $"{"abc"}{123.45}" are not. +For example, $“Hello”, $“{cs1}, world!” (given `const string cs1 = $"Hello";`), $“{“Hello,” + $“world!"}”, and $“xxx{(true ? $“{“X”}” : $“{$“{“Y”}”}”)}yyy” are all constant interpolated strings. However, $“{123}” and $“{“abc”}{123.45}” are not. For simplicity, the term *ISE* is used throughout this specification to mean either an *interpolated_string_expression* or an *additive_expression* composed entirely of *interpolated_string_expression*s and binary `+` operators. @@ -3977,13 +3977,13 @@ A *with_expression* is not permitted as a statement. The receiver type shall be non-`void` and of some record class, record struct, or non-record struct type. -*identifier* shall be an accessible instance field or property of the receiver's type. +*identifier* shall be an accessible instance field or property of the receiver’s type. All non-positional properties being changed shall have both set and init accessors. This expression is evaluated as follows: -- For a record class type, the receiver's clone method ([§15.16.6.4](classes.md#151664-copy-and-clone-members)) is invoked, and its result is converted to the receiver’s type. +- For a record class type, the receiver’s clone method ([§15.16.6.4](classes.md#151664-copy-and-clone-members)) is invoked, and its result is converted to the receiver’s type. - For a record struct or non-record struct type, the receiver is copied. - Each `member_initializer` is processed the same way as an assignment to a field or property access of the result of the conversion. Assignments are processed in lexical order. If *member_initializer_list* is omitted, no members are changed. @@ -7584,7 +7584,7 @@ If any `nint`/`nuint` values are not representable as `Int32`/`UInt32`, or the r > } > ``` > -> The preceding example emits an error because the result of the expression `int.MaxValue + 1` isn't representable as `Int32`. On machines where the size of a `nint` is greater than 32 bits, the expression would succeed at runtime. *end example* +> The preceding example emits an error because the result of the expression `int.MaxValue + 1` isn’t representable as `Int32`. On machines where the size of a `nint` is greater than 32 bits, the expression would succeed at runtime. *end example* Unless a constant expression is explicitly placed in an `unchecked` context, overflows that occur in integral-type arithmetic operations and conversions during the compile-time evaluation of the expression always cause compile-time errors ([§12.8.20](expressions.md#12820-the-checked-and-unchecked-operators)). diff --git a/standard/lexical-structure.md b/standard/lexical-structure.md index bf8ecee0b..ba5893705 100644 --- a/standard/lexical-structure.md +++ b/standard/lexical-structure.md @@ -1577,7 +1577,7 @@ A `#line hidden` directive has no effect on the source location information repo > *Note*: Although a *PP_Compilation_Unit_Name* might contain text that looks like an escape sequence, such text is not an escape sequence; in this context a ‘`\`’ character simply designates an ordinary backslash character. *end note* -Together, the tokens *PP_Start_Line_Character* '-' *PP_End_Line_Character* specify a span of characters in the source file identified by *PP_Compilation_Unit_Name* (the ***mapped file***). +Together, the tokens *PP_Start_Line_Character* ‘-’ *PP_End_Line_Character* specify a span of characters in the source file identified by *PP_Compilation_Unit_Name* (the ***mapped file***). *PP_Start_Line_Character* represents a start position in the mapped file, specified as a line (*PP_Start_Line*) and column (*PP_Start_Character*) pair; for example, `(1,1)`. This position corresponds to the first character on the line following the directive in the generated code. diff --git a/standard/patterns.md b/standard/patterns.md index a342e817e..5de94722f 100644 --- a/standard/patterns.md +++ b/standard/patterns.md @@ -650,15 +650,15 @@ It is a compile-time error for a pattern variable to be declared beneath a `not` In a *conjunctive_pattern*, the *input type* of the second pattern is narrowed by the *type narrowing* requirements of first pattern of the `and`. The *narrowed type* of a pattern `P` is defined as follows: -- If `P` is a type pattern, the *narrowed type* is the type of the type pattern's type. -- Otherwise, if `P` is a declaration pattern, the *narrowed type* is the type of the declaration pattern's type. +- If `P` is a type pattern, the *narrowed type* is the type of the type pattern’s type. +- Otherwise, if `P` is a declaration pattern, the *narrowed type* is the type of the declaration pattern’s type. - Otherwise, if `P` is a recursive pattern that gives an explicit type, the *narrowed type* is that type. - Otherwise, if `P` is matched via the rules for `ITuple` in a *positional_pattern* ([§11.2.5](patterns.md#1125-positional-pattern)), the *narrowed type* is the type `System.ITuple`. - Otherwise, if `P` is a constant pattern where the constant is not the null constant and where the expression has no *constant expression conversion* to the *input type*, the *narrowed type* is the type of the constant. - Otherwise, if `P` is a relational pattern where the constant expression has no *constant expression conversion* to the *input type*, the *narrowed type* is the type of the constant. - Otherwise, if `P` is an `or` pattern, the *narrowed type* is the common type of the *narrowed type* of the subpatterns if such a common type exists. For this purpose, the common type algorithm considers only identity, boxing, and implicit reference conversions, and it considers all subpatterns of a sequence of `or` patterns (ignoring parenthesized patterns). - Otherwise, if `P` is an `and` pattern, the *narrowed type* is the *narrowed type* of the right pattern. Moreover, the *narrowed type* of the left pattern is the *input type* of the right pattern. -- Otherwise the *narrowed type* of `P` is `P`'s input type. +- Otherwise the *narrowed type* of `P` is `P`’s input type. > *Note*: As indicated by the grammar, `not` has precedence over `and`, which has precedence over `or`. This can be explicitly indicated or overridden by using parentheses. *end note* diff --git a/standard/statements.md b/standard/statements.md index b6de32c08..9c36abc63 100644 --- a/standard/statements.md +++ b/standard/statements.md @@ -1194,7 +1194,7 @@ Before the process described in [§13.9.5.1](statements.md#13951-general), the f If the process in [§13.9.5.1](statements.md#13951-general) completes without producing a single collection type, enumerator type, and iteration type, the following steps are taken: - If there is an implicit conversion from `X` to the `System.Collections.IEnumerable` interface, then the collection type is this interface, the enumerator type is the interface `System.Collections.IEnumerator`, and the iteration type is `object`. -- Otherwise, determine whether the type 'X' has an appropriate `GetEnumerator` extension method: +- Otherwise, determine whether the type ‘X’ has an appropriate `GetEnumerator` extension method: - Perform extension method lookup on the type `X` with identifier `GetEnumerator`. If the member lookup does not produce a match, or it produces an ambiguity, or produces a match which is not a method group, an error is produced, and no further steps are taken. It is recommended that a warning be issued if member lookup produces anything except a method group or no match. - Perform overload resolution using the resulting method group and a single argument of type `X`. If overload resolution produces no applicable methods, results in an ambiguity, or results in a single best method but that method is not accessible, an error is produced an no further steps are taken. - This resolution permits the first argument to be passed by ref if `X` is a struct type, and the ref kind is `in`. diff --git a/standard/structs.md b/standard/structs.md index 801cc85c1..630ef1e66 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -334,7 +334,7 @@ private bool PrintMembers(System.Text.StringBuilder builder); This method performs the following tasks: -1. For each of the record struct’s printable members (non-static public field and readable property members), appends that member's name followed by “` = `“ followed by the member's value separated with “`, “`, +1. For each of the record struct’s printable members (non-static public field and readable property members), appends that member’s name followed by “` = `“ followed by the member’s value separated with “`, “`, 2. Returns true if the record struct has printable members. For a member that has a value type, its value shall be converted to a string representation. @@ -357,7 +357,7 @@ This method performs the following tasks: 1. Creates a `StringBuilder` instance, 2. Appends the record struct name to the builder, followed by “` { `“, -3. Invokes the record struct's `PrintMembers` method giving it the builder, followed by “` `” if it returned true, +3. Invokes the record struct’s `PrintMembers` method giving it the builder, followed by “` `” if it returned true, 4. Appends “`}`”, 5. Returns the builder’s contents with `builder.ToString()`. diff --git a/standard/unsafe-code.md b/standard/unsafe-code.md index dc05a3aa9..a69ee7d52 100644 --- a/standard/unsafe-code.md +++ b/standard/unsafe-code.md @@ -117,7 +117,7 @@ When the `unsafe` modifier is used on a partial type declaration ([§15.2.7](cla ### 24.3.1 General -A ***pointer*** is a variable that is capable of containing the address of a variable or static method, referred to as that pointer's target. A pointer with value `null` is a ***null pointer***, and does not currently point to a variable or static method. The act of attempting to access the target of a pointer is called ***dereferencing*** ([§24.6.2](unsafe-code.md#2462-pointer-indirection) and [§24.6.4](unsafe-code.md#2464-pointer-element-access)). +A ***pointer*** is a variable that is capable of containing the address of a variable or static method, referred to as that pointer’s target. A pointer with value `null` is a ***null pointer***, and does not currently point to a variable or static method. The act of attempting to access the target of a pointer is called ***dereferencing*** ([§24.6.2](unsafe-code.md#2462-pointer-indirection) and [§24.6.4](unsafe-code.md#2464-pointer-element-access)). In an unsafe context, a *type* ([§8.1](types.md#81-general)) can be a *pointer_type*. A *pointer_type* may also be the element type of an array ([§17](arrays.md#17-arrays)). A *pointer_type* may also be used in a typeof expression ([§12.8.18](expressions.md#12818-the-typeof-operator)) outside of an unsafe context (as such usage is not unsafe). diff --git a/standard/variables.md b/standard/variables.md index a2b541d53..0c649564c 100644 --- a/standard/variables.md +++ b/standard/variables.md @@ -1051,7 +1051,7 @@ let *E₀* be the expression obtained by textually removing the leading `?` from > *Note*: The concept of “directly contains” allows skipping over relatively simple “wrapper” expressions when analyzing conditional accesses that are compared to other values. For example, in general, `((a?.b(out x))!) == true` is expected to result in the same flow state as `a?.b == true`. > -> The intent is to allow analysis to function in the presence of a number of possible conversions on a conditional access. Propagating out “state when not null” is not possible when the conversion is user-defined, though, since one can't count on user-defined conversions to honor the constraint that the output is non-null only if the input is non-null. The only exception to this is when the user-defined conversion’s input is a non-nullable value type. For example: +> The intent is to allow analysis to function in the presence of a number of possible conversions on a conditional access. Propagating out “state when not null” is not possible when the conversion is user-defined, though, since one can’t count on user-defined conversions to honor the constraint that the output is non-null only if the input is non-null. The only exception to this is when the user-defined conversion’s input is a non-nullable value type. For example: > > ```csharp > public struct S1 { } @@ -1090,7 +1090,7 @@ For an expression *expr*, where *expr* is a constant expression with a `bool` va - If *expr* is a constant expression with value *true*, and the state of *v* before *expr* is “not definitely assigned,” then the state of *v* after *expr* is “definitely assigned when false.” - If *expr* is a constant expression with value *false*, and the state of *v* before *expr* is “not definitely assigned,” then the state of *v* after *expr* is “definitely assigned when true.” -> *Note*: It is assumed that if an expression has a constant value bool `false`, that it's impossible to reach any branch that requires the expression to return `true`. Therefore, variables are assumed to be definitely assigned in such branches. +> *Note*: It is assumed that if an expression has a constant value bool `false`, that it’s impossible to reach any branch that requires the expression to return `true`. Therefore, variables are assumed to be definitely assigned in such branches. > > Being in a conditional state *before* visiting a constant expression, is never expected, so there is no need to account for scenarios such as “*expr* is a constant expression with value *true* and the state of *v* before *expr* is definitely assigned when true.” *end note* @@ -1132,14 +1132,14 @@ All of the above rules are commutative. > > Some consequences of these rules are: > -> - `if (a?.b(out var x) == true) x() else x();` will error in the 'else' branch -> - `if (a?.b(out var x) == 42) x() else x();` will error in the 'else' branch -> - `if (a?.b(out var x) == false) x() else x();` will error in the 'else' branch -> - `if (a?.b(out var x) == null) x() else x();` will error in the 'then' branch -> - `if (a?.b(out var x) != true) x() else x();` will error in the 'then' branch -> - `if (a?.b(out var x) != 42) x() else x();` will error in the 'then' branch -> - `if (a?.b(out var x) != false) x() else x();` will error in the 'then' branch -> - `if (a?.b(out var x) != null) x() else x();` will error in the 'else' branch +> - `if (a?.b(out var x) == true) x() else x();` will error in the ‘else’ branch +> - `if (a?.b(out var x) == 42) x() else x();` will error in the ‘else’ branch +> - `if (a?.b(out var x) == false) x() else x();` will error in the ‘else’ branch +> - `if (a?.b(out var x) == null) x() else x();` will error in the ‘then’ branch +> - `if (a?.b(out var x) != true) x() else x();` will error in the ‘then’ branch +> - `if (a?.b(out var x) != 42) x() else x();` will error in the ‘then’ branch +> - `if (a?.b(out var x) != false) x() else x();` will error in the ‘then’ branch +> - `if (a?.b(out var x) != null) x() else x();` will error in the ‘else’ branch > > *end note* @@ -1160,7 +1160,7 @@ where *T* is any type or pattern: - If *E* directly contains a null-conditional expression, and the state of *v* after the non-conditional counterpart *E₀* is “definitely assigned,” and `T` is a pattern that matches a `null` input, then the state of *v* after *expr* is “definitely assigned when false.” - If *E* is of type `bool` and `T` is a pattern that only matches a `true` input, then the definite-assignment state of *v* after *expr* is the same as the definite-assignment state of *v* after *E*. - If *E* is of type `bool` and `T` is a pattern that only matches a `false` input, then the definite-assignment state of *v* after *expr* is the same as the definite-assignment state of *v* after the logical negation expression `!`*expr*. - - Otherwise, if the definite-assignment state of *v* after *E* is "definitely assigned," then the definite-assignment state of *v* after *expr* is "definitely assigned." + - Otherwise, if the definite-assignment state of *v* after *E* is “definitely assigned,” then the definite-assignment state of *v* after *expr* is “definitely assigned.” > *Note*: This subclause addresses similar scenarios as [§9.4.4.37](variables.md#94437--expressions). It does not, however, address recursive patterns; e.g., `(a?.b(out x), c?.d(out y)) is (object, object)`. *end note*