From 2b6936d8714d9258d59eca0385fab29de11da0db Mon Sep 17 00:00:00 2001 From: Nigel-Ecma Date: Tue, 10 Mar 2026 11:55:27 +1300 Subject: [PATCH] Expand all contractions except those used as examples. --- standard/attributes.md | 28 ++++++++++++++-------------- standard/basic-concepts.md | 4 ++-- standard/classes.md | 24 ++++++++++++------------ standard/conversions.md | 6 +++--- standard/exceptions.md | 2 +- standard/expressions.md | 8 ++++---- standard/interfaces.md | 14 +++++++------- standard/patterns.md | 6 +++--- standard/statements.md | 8 ++++---- standard/structs.md | 2 +- standard/types.md | 10 +++++----- standard/unsafe-code.md | 8 ++++---- standard/variables.md | 6 +++--- 13 files changed, 63 insertions(+), 63 deletions(-) diff --git a/standard/attributes.md b/standard/attributes.md index 773f25f35..d3cd6d8ae 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -467,7 +467,7 @@ The compilation of an *attribute* with attribute class `T`, *positional_argumen - Let `Name` be the *identifier* of the *named_argument* `Arg`. - `Name` shall identify a non-static read-write public field or property on `T`. If `T` has no such field or property, then a compile-time error occurs. - If any of the values within *positional_argument_list* `P` or one of the values within *named_argument_list* `N` is of type `System.String` and the value is not well-formed as defined by the Unicode Standard, it is implementation-defined whether the value compiled is equal to the run-time value retrieved ([§23.4.3](attributes.md#2343-run-time-retrieval-of-an-attribute-instance)). - > *Note*: As an example, a string which contains a high surrogate UTF-16 code unit which isn’t immediately followed by a low surrogate code unit is not well-formed. *end note* + > *Note*: As an example, a string which contains a high surrogate UTF-16 code unit which is not immediately followed by a low surrogate code unit is not well-formed. *end note* - Store the following information (for run-time instantiation of the attribute) in the assembly output by the compiler as a result of compiling the program containing the attribute: the attribute class `T`, the instance constructor `C` on `T`, the *positional_argument_list* `P`, the *named_argument_list* `N`, and the associated program entity `E`, with the values resolved completely at compile-time. ### 23.4.3 Run-time retrieval of an attribute instance @@ -840,7 +840,7 @@ For invocations that occur within declarations of instance constructors, static #### 23.5.7.1 General -The attributes in this subclause are used to provide additional information to support a compiler that provides nullability and null-state diagnostics ([§8.9.5](types.md#895-nullabilities-and-null-states)). A compiler isn’t required to perform any null-state diagnostics. The presence or absence of these attributes do not affect the language nor the behavior of a program. A compiler that doesn’t provide null-state diagnostics shall read and ignore the presence of these attributes. A compiler that provides null-state diagnostics shall use the meaning defined in this subclause for any of these attributes which it uses to inform its diagnostics. +The attributes in this subclause are used to provide additional information to support a compiler that provides nullability and null-state diagnostics ([§8.9.5](types.md#895-nullabilities-and-null-states)). A compiler is not required to perform any null-state diagnostics. The presence or absence of these attributes do not affect the language nor the behavior of a program. A compiler that does not provide null-state diagnostics shall read and ignore the presence of these attributes. A compiler that provides null-state diagnostics shall use the meaning defined in this subclause for any of these attributes which it uses to inform its diagnostics. The code-analysis attributes are declared in namespace `System.Diagnostics.CodeAnalysis`. @@ -851,8 +851,8 @@ The code-analysis attributes are declared in namespace `System.Diagnostics.CodeA `MaybeNull` ([§23.5.7.6](attributes.md#23576-the-maybenull-attribute)) | A non-nullable return value may be null. `NotNull` ([§23.5.7.8](attributes.md#23578-the-notnull-attribute)) | A nullable return value will never be null. `MaybeNullWhen` ([§23.5.7.7](attributes.md#23577-the-maybenullwhen-attribute)) | A non-nullable argument may be null when the method returns the specified `bool` value. -`NotNullWhen` ([§23.5.7.10](attributes.md#235710-the-notnullwhen-attribute)) | A nullable argument won’t be null when the method returns the specified `bool` value. -`NotNullIfNotNull` ([§23.5.7.9](attributes.md#23579-the-notnullifnotnull-attribute)) | A return value isn’t null if the argument for the specified parameter isn’t null. +`NotNullWhen` ([§23.5.7.10](attributes.md#235710-the-notnullwhen-attribute)) | A nullable argument will not be null when the method returns the specified `bool` value. +`NotNullIfNotNull` ([§23.5.7.9](attributes.md#23579-the-notnullifnotnull-attribute)) | A return value is not null if the argument for the specified parameter is not null. `DoesNotReturn` ([§23.5.7.4](attributes.md#23574-the-doesnotreturn-attribute)) | This method never returns. `DoesNotReturnIf` ([§23.5.7.5](attributes.md#23575-the-doesnotreturnif-attribute)) | This method never returns if the associated `bool` parameter has the specified value. @@ -911,7 +911,7 @@ Specifies that a null value is disallowed as an input even if the corresponding > } > ``` > -> The get accessor could return the default value of `null`, so a compiler may warn that it must be checked before access. Furthermore, it warns callers that, even though it could be null, callers shouldn’t explicitly set it to null. *end example* +> The get accessor could return the default value of `null`, so a compiler may warn that it must be checked before access. Furthermore, it warns callers that, even though it could be null, callers should not explicitly set it to null. *end example* #### 23.5.7.4 The DoesNotReturn attribute @@ -942,7 +942,7 @@ Specifies that a given method never returns. > } > ``` > -> The presence of the attribute helps a compiler in a number of ways. First, a compiler can issue a warning if there’s a path where the method can exit without throwing an exception. Second, a compiler can suppress nullable warnings in any code after a call to that method, until an appropriate catch clause is found. Third, the unreachable code won’t affect any null states. +> The presence of the attribute helps a compiler in a number of ways. First, a compiler can issue a warning if there is a path where the method can exit without throwing an exception. Second, a compiler can suppress nullable warnings in any code after a call to that method, until an appropriate catch clause is found. Third, the unreachable code will not affect any null states. > > The attribute does not change reachability ([§13.2](statements.md#132-end-points-and-reachability)) or definite assignment ([§9.4](variables.md#94-definite-assignment)) analysis based on the presence of this attribute. It is used only to impact nullability warnings. *end example* @@ -962,7 +962,7 @@ 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"); +> $"argument {argumentName} cannot be null"); > } > } > @@ -1027,11 +1027,11 @@ Specifies that a nullable value will never be `null` if the method returns (rath > } > ``` > -> When nullable reference types are enabled, method `ThrowWhenNull` compiles without warnings. When that method returns, the `value` argument is guaranteed to be not `null`. However, it’s acceptable to call `ThrowWhenNull` with a null reference. *end example* +> When nullable reference types are enabled, method `ThrowWhenNull` compiles without warnings. When that method returns, the `value` argument is guaranteed to be not `null`. However, it is acceptable to call `ThrowWhenNull` with a null reference. *end example* #### 23.5.7.9 The NotNullIfNotNull attribute -Specifies that a return value isn’t `null` if the argument for the specified parameter isn’t `null`. +Specifies that a return value is not `null` if the argument for the specified parameter is not `null`. > *Example*: The null state of a return value could depend on the null state of one or more arguments. To assist a compiler’s analysis when a method always returns a non-null value when certain arguments are not `null` the `NotNullIfNotNull` attribute may be used. Consider the following method: > @@ -1041,7 +1041,7 @@ Specifies that a return value isn’t `null` if the argument for the specified p > string GetTopLevelDomainFromFullUrl(string url) { ... } > ``` > -> If the `url` argument isn’t `null`, `null` isn’t returned. When nullable references are enabled, that signature works correctly, provided the API never accepts a null argument. However, if the argument could be null, then the return value could also be null. To express that contract correctly, annotate this method as follows: +> If the `url` argument is not `null`, `null` is not returned. When nullable references are enabled, that signature works correctly, provided the API never accepts a null argument. However, if the argument could be null, then the return value could also be null. To express that contract correctly, annotate this method as follows: > > > ```csharp @@ -1054,9 +1054,9 @@ Specifies that a return value isn’t `null` if the argument for the specified p #### 23.5.7.10 The NotNullWhen attribute -Specifies that a nullable argument won’t be `null` when the method returns the specified `bool` value. +Specifies that a nullable argument will not be `null` when the method returns the specified `bool` value. -> *Example*: The library method `String.IsNullOrEmpty(String)` returns `true` when the argument is `null` or an empty string. It’s a form of null-check: Callers don’t need to null-check the argument if the method returns `false`. To make a method like this nullable aware, make the parameter type a nullable reference type, and add the NotNullWhen attribute: +> *Example*: The library method `String.IsNullOrEmpty(String)` returns `true` when the argument is `null` or an empty string. It is a form of null-check: Callers do not need to null-check the argument if the method returns `false`. To make a method like this nullable aware, make the parameter type a nullable reference type, and add the NotNullWhen attribute: > > > ```csharp @@ -1073,10 +1073,10 @@ Specifies the parameter representing the `CancellationToken` for an asynchronous It is an error if the `System.Runtime.CompilerServices.EnumeratorCancellation` attribute is applied to more than one parameter. The compiler may produce a warning if: - The `EnumeratorCancellation` attribute is applied to a parameter of a type other than `CancellationToken`, -- or if the `EnumeratorCancellation` attribute is applied to a parameter on a method that isn’t an asynchronous iterator ([§15.15](classes.md#1515-synchronous-and-asynchronous-iterators)), +- or if the `EnumeratorCancellation` attribute is applied to a parameter on a method that is not an asynchronous iterator ([§15.15](classes.md#1515-synchronous-and-asynchronous-iterators)), - or if the `EnumeratorCancellation` attribute is applied to a parameter on a method that returns an asynchronous enumerable interface ([§15.15.3](classes.md#15153-enumerable-interfaces)) rather than an asynchronous enumerator interface ([§15.15.2](classes.md#15152-enumerator-interfaces)). -The iterator won’t have access to the `CancellationToken` argument for `GetAsyncEnumerator` when no attributes have this parameter. +The iterator will not have access to the `CancellationToken` argument for `GetAsyncEnumerator` when no attributes have this parameter. > *Example*: The method `GetStringsAsync()` is an asynchronous iterator. Before doing any work to retrieve the next value, it checks the cancellation token to determine if the iteration should be canceled. If cancellation is requested, no further action is taken. > diff --git a/standard/basic-concepts.md b/standard/basic-concepts.md index 6bacb48f0..46ad70efa 100644 --- a/standard/basic-concepts.md +++ b/standard/basic-concepts.md @@ -209,7 +209,7 @@ 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* -Members of a type are either declared in the type declaration or ***inherited*** from the base class of the type. When a type inherits from a base class, all members of the base class, except instance constructors, finalizers, and static constructors become members of the derived type. The declared accessibility of a base class member does not control whether the member is inherited—inheritance extends to any member that isn’t an instance constructor, static constructor, or finalizer. +Members of a type are either declared in the type declaration or ***inherited*** from the base class of the type. When a type inherits from a base class, all members of the base class, except instance constructors, finalizers, and static constructors become members of the derived type. The declared accessibility of a base class member does not control whether the member is inherited—inheritance extends to any member that is not an instance constructor, static constructor, or finalizer. > *Note*: However, an inherited member might not be accessible in a derived type, for example because of its declared accessibility ([§7.5.2](basic-concepts.md#752-declared-accessibility)). *end note* @@ -806,7 +806,7 @@ Contrary to hiding a name from an outer scope, hiding a visible name from an inh > } > ``` > -> the declaration of `F` in `Derived` causes a warning to be reported. Hiding an inherited name is specifically not an error, since that would preclude separate evolution of base classes. For example, the above situation might have come about because a later version of `Base` introduced an `F` method that wasn’t present in an earlier version of the class. +> the declaration of `F` in `Derived` causes a warning to be reported. Hiding an inherited name is specifically not an error, since that would preclude separate evolution of base classes. For example, the above situation might have come about because a later version of `Base` introduced an `F` method that was not present in an earlier version of the class. > > *end example* diff --git a/standard/classes.md b/standard/classes.md index 199e77de3..eb52aafae 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -91,7 +91,7 @@ When a non-abstract class is derived from an abstract class, the non-abstract cl > } > ``` > -> the abstract class `A` introduces an abstract method `F`. Class `B` introduces an additional method `G`, but since it doesn’t provide an implementation of `F`, `B` shall also be declared abstract. Class `C` overrides `F` and provides an actual implementation. Since there are no abstract members in `C`, `C` is permitted (but not required) to be non-abstract. +> the abstract class `A` introduces an abstract method `F`. Class `B` introduces an additional method `G`, but since it does not provide an implementation of `F`, `B` shall also be declared abstract. Class `C` overrides `F` and provides an actual implementation. Since there are no abstract members in `C`, `C` is permitted (but not required) to be non-abstract. > > *end example* @@ -440,9 +440,9 @@ The class type, reference type constraint, and secondary constraints can include - If the constraint does not include the nullable type annotation, the type argument is expected to be a non-nullable reference type. A compiler may issue a warning if the type argument is a nullable reference type. - If the constraint includes the nullable type annotation, the constraint is satisfied by both a non-nullable reference type and a nullable reference type. -The nullability of the type argument need not match the nullability of the type parameter. A compiler may issue a warning if the nullability of the type parameter doesn’t match the nullability of the type argument. +The nullability of the type argument need not match the nullability of the type parameter. A compiler may issue a warning if the nullability of the type parameter does not match the nullability of the type argument. -> *Note*: To specify that a type argument is a nullable reference type, don’t add the nullable type annotation as a constraint (use `T : class` or `T : BaseClass`), but use `T?` throughout the generic declaration to indicate the corresponding nullable reference type for the type argument. *end note* +> *Note*: To specify that a type argument is a nullable reference type, do not add the nullable type annotation as a constraint (use `T : class` or `T : BaseClass`), but use `T?` throughout the generic declaration to indicate the corresponding nullable reference type for the type argument. *end note* The nullable type annotation, `?`, can only be used on a type parameter that has the value type constraint, the reference type constraint without the *nullable_type_annotation*, or a class type constraint without the *nullable_type_annotation*. @@ -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 is not 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. @@ -534,7 +534,7 @@ The unmanaged type constraint specifies that a type argument used for the type p Because `unmanaged` is not a keyword, in *primary_constraint* the unmanaged 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 `unmanaged` succeeds it is treated as a `class_type`. Otherwise it is treated as the unmanaged constraint. -Pointer types are never allowed to be type arguments, and don’t satisfy any type constraints, even unmanaged, despite being unmanaged types. +Pointer types are never allowed to be type arguments, and do not satisfy any type constraints, even unmanaged, despite being unmanaged types. If a constraint is a class type, an interface type, or a type parameter, that type specifies a minimal “base type” that every type argument used for that type parameter shall support. Whenever a constructed type or generic method is used, the type argument is checked against the constraints on the type parameter at compile-time. The type argument supplied shall satisfy the conditions described in [§8.4.5](types.md#845-satisfying-constraints). @@ -1033,7 +1033,7 @@ A *class_member_declaration* is permitted to declare a member with the same name An inherited member `M` is considered to be ***available*** if `M` is accessible and there is no other inherited accessible member N that already hides `M`. Implicitly hiding an inherited member is not considered an error, but a compiler shall issue a warning unless the declaration of the derived class member includes a `new` modifier to explicitly indicate that the derived member is intended to hide the base member. If one or more parts of a partial declaration ([§15.2.7](classes.md#1527-partial-type-declarations)) of a nested type include the `new` modifier, no warning is issued if the nested type hides an available inherited member. -If a `new` modifier is included in a declaration that doesn’t hide an available inherited member, a warning to that effect is issued. +If a `new` modifier is included in a declaration that does not hide an available inherited member, a warning to that effect is issued. ### 15.3.6 Access modifiers @@ -1775,7 +1775,7 @@ Constants and readonly fields have different binary versioning semantics. When a > } > ``` > -> The `Program1` and `Program2` namespaces denote two programs that are compiled separately. Because `Program1.Utils.X` is declared as a `static readonly` field, the value output by the `Console.WriteLine` statement is not known at compile-time, but rather is obtained at run-time. Thus, if the value of `X` is changed and `Program1` is recompiled, the `Console.WriteLine` statement will output the new value even if `Program2` isn’t recompiled. However, had `X` been a constant, the value of `X` would have been obtained at the time `Program2` was compiled, and would remain unaffected by changes in `Program1` until `Program2` is recompiled. +> The `Program1` and `Program2` namespaces denote two programs that are compiled separately. Because `Program1.Utils.X` is declared as a `static readonly` field, the value output by the `Console.WriteLine` statement is not known at compile-time, but rather is obtained at run-time. Thus, if the value of `X` is changed and `Program1` is recompiled, the `Console.WriteLine` statement will output the new value even if `Program2` is not recompiled. However, had `X` been a constant, the value of `X` would have been obtained at the time `Program2` was compiled, and would remain unaffected by changes in `Program1` until `Program2` is recompiled. > > *end example* @@ -2441,7 +2441,7 @@ A method declared as a partial method ([§15.6.9](classes.md#1569-partial-method A parameter declared with a `params` modifier is a parameter array. If a parameter list includes a parameter array, it shall be the last parameter in the list and it shall be of a single-dimensional array type. -> *Example*: The types `string[]` and `string[][]` can be used as the type of a parameter array, but the type `string[,]` can not. *end example* +> *Example*: The types `string[]` and `string[][]` can be used as the type of a parameter array, but the type `string[,]` cannot. *end example* @@ -3665,7 +3665,7 @@ Unlike public fields, properties provide a separation between an object’s inte > > the value of the `Next` property depends on the number of times the property has previously been accessed. Thus, accessing the property produces an observable side effect, and the property should be implemented as a method instead. > -> The “no side-effects” convention for get accessors doesn’t mean that get accessors should always be written simply to return values stored in fields. Indeed, get accessors often compute the value of a property by accessing multiple fields or invoking methods. However, a properly designed get accessor performs no actions that cause observable changes in the state of the object. +> The “no side-effects” convention for get accessors does not mean that get accessors should always be written simply to return values stored in fields. Indeed, get accessors often compute the value of a property by accessing multiple fields or invoking methods. However, a properly designed get accessor performs no actions that cause observable changes in the state of the object. > > *end example* @@ -5013,7 +5013,7 @@ Variable initializers are transformed into assignment statements, and these assi > } > ``` > -> contains several variable initializers; it also contains constructor initializers of both forms (`base` and `this`). The example corresponds to the code shown below, where each comment indicates an automatically inserted statement (the syntax used for the automatically inserted constructor invocations isn’t valid, but merely serves to illustrate the mechanism). +> contains several variable initializers; it also contains constructor initializers of both forms (`base` and `this`). The example corresponds to the code shown below, where each comment indicates an automatically inserted statement (the syntax used for the automatically inserted constructor invocations is not valid, but merely serves to illustrate the mechanism). > > ```csharp > class A @@ -5480,7 +5480,7 @@ A compiler shall generate code that uses the «TaskBuilderType» to implement th - `SetStateMachine(IAsyncStateMachine)` may be called by the compiler-generated `IAsyncStateMachine` implementation to identify the instance of the builder associated with a state machine instance, particularly for cases where the state machine is implemented as a value type. - If the builder calls `stateMachine.SetStateMachine(stateMachine)`, the `stateMachine` will call `builder.SetStateMachine(stateMachine)` on the *builder instance associated with* `stateMachine`. -> *Note*: For both `SetResult(T result)` and `«TaskType» Task { get; }`, the parameter and argument respectively must be identity convertible to `T`. This allows a task-type builder to support types such as tuples, where two types that aren’t the same are identity convertible. *end note* +> *Note*: For both `SetResult(T result)` and `«TaskType» Task { get; }`, the parameter and argument respectively must be identity convertible to `T`. This allows a task-type builder to support types such as tuples, where two types that are not the same are identity convertible. *end note* ### 15.14.3 Evaluation of a task-returning async function @@ -5583,7 +5583,7 @@ The precise action performed by `MoveNext` or `MoveNextAsync` depends on the sta When `MoveNext` executes the iterator block, execution can be interrupted in four ways: By a `yield return` statement, by a `yield break` statement, by encountering the end of the iterator block, and by an exception being thrown and propagated out of the iterator block. -> *Note*: `MoveNextAsync` is suspended if it evaluates an `await` expression that awaits a task type that hasn’t completed. *end note* +> *Note*: `MoveNextAsync` is suspended if it evaluates an `await` expression that awaits a task type that has not completed. *end note* - When a `yield return` statement is encountered ([§9.4.4.20](variables.md#94420-yield-statements)): - The expression given in the statement is evaluated, implicitly converted to the yield type, and assigned to the `Current` property of the enumerator object. diff --git a/standard/conversions.md b/standard/conversions.md index c37992027..7771db426 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -549,7 +549,7 @@ For a *type_parameter* `T` that is known to be a reference type ([§15.2.5](clas - From the effective base class `C` of `T` to `T` and from any base class of `C` to `T`. - From any *interface_type* to `T`. -- From `T` to any *interface_type* `I` provided there isn’t already an implicit reference conversion from `T` to `I`. +- From `T` to any *interface_type* `I` provided there is not already an implicit reference conversion from `T` to `I`. - From a *type_parameter* `U` to `T` provided that `T` depends on `U` ([§15.2.5](classes.md#1525-type-parameter-constraints)). > *Note*: Since `T` is known to be a reference type, within the scope of `T`, the run-time type of U will always be a reference type, even if `U` is not known to be a reference type at compile-time. *end note* @@ -678,7 +678,7 @@ A user-defined implicit conversion from an expression `E` to a type `T` is pro - If `E` has a type, let `S` be that type. - If `S` or `T` are nullable value types, let `Sᵢ` and `Tᵢ` be their underlying types, otherwise let `Sᵢ` and `Tᵢ` be `S` and `T`, respectively. - If `Sᵢ` or `Tᵢ` are type parameters, let `S₀` and `T₀` be their effective base classes, otherwise let `S₀` and `T₀` be `Sᵢ` and `Tᵢ`, respectively. -- Find the set of types, `D`, from which user-defined conversion operators will be considered. This set consists of `S₀` (if `S₀` exists and is a class or struct), the base classes of `S₀` (if `S₀` exists and is a class), and `T₀` (if `T₀` is a class or struct). A type is added to the set `D` only if an identity conversion to another type already included in the set doesn’t exist. +- Find the set of types, `D`, from which user-defined conversion operators will be considered. This set consists of `S₀` (if `S₀` exists and is a class or struct), the base classes of `S₀` (if `S₀` exists and is a class), and `T₀` (if `T₀` is a class or struct). A type is added to the set `D` only if an identity conversion to another type already included in the set does not exist. - Find the set of applicable user-defined and lifted conversion operators, `U`. This set consists of the user-defined and lifted implicit conversion operators declared by the classes or structs in `D` that convert from a type encompassing `E` to a type encompassed by `T`. If `U` is empty, the conversion is undefined and a compile-time error occurs. - Find the most-specific source type, `Sₓ`, of the operators in `U`: @@ -706,7 +706,7 @@ A user-defined explicit conversion from an expression `E` to a type `T` is pro - If `E` has a type, let `S` be that type. - If `S` or `T` are nullable value types, let `Sᵢ` and `Tᵢ` be their underlying types, otherwise let `Sᵢ` and `Tᵢ` be `S` and `T`, respectively. - If `Sᵢ` or `Tᵢ` are type parameters, let `S₀` and `T₀` be their effective base classes, otherwise let `S₀` and `T₀` be `Sᵢ` and `Tᵢ`, respectively. -- Find the set of types, `D`, from which user-defined conversion operators will be considered. This set consists of `S₀` (if `S₀` exists and is a class or struct), the base classes of `S₀` (if `S₀` exists and is a class), `T₀` (if `T₀` is a class or struct), and the base classes of `T₀` (if `T₀` is a class). A type is added to the set `D` only if an identity conversion to another type already included in the set doesn’t exist. +- Find the set of types, `D`, from which user-defined conversion operators will be considered. This set consists of `S₀` (if `S₀` exists and is a class or struct), the base classes of `S₀` (if `S₀` exists and is a class), `T₀` (if `T₀` is a class or struct), and the base classes of `T₀` (if `T₀` is a class). A type is added to the set `D` only if an identity conversion to another type already included in the set does not exist. - Find the set of applicable user-defined and lifted conversion operators, `U`. This set consists of the user-defined and lifted implicit or explicit conversion operators declared by the classes or structs in `D` that convert from a type encompassing `E` or encompassed by `S` (if it exists) to a type encompassing or encompassed by `T`. If `U` is empty, the conversion is undefined and a compile-time error occurs. - Find the most-specific source type, `Sₓ`, of the operators in `U`: - If S exists and any of the operators in `U` convert from `S`, then `Sₓ` is `S`. diff --git a/standard/exceptions.md b/standard/exceptions.md index a6e95b090..8d487f6e2 100644 --- a/standard/exceptions.md +++ b/standard/exceptions.md @@ -25,7 +25,7 @@ The value of these properties can be specified in calls to the instance construc Exceptions are handled by a `try` statement ([§13.11](statements.md#1311-the-try-statement)). -When an exception is thrown ([§22.2](exceptions.md#222-causes-of-exceptions)), the system searches for the nearest catch clause that can handle the exception, as determined by the run-time type of the exception. First, the current method is searched for a lexically enclosing `try` statement, and the associated `catch` clauses of the `try` statement are considered in order. If that fails, the method that called the current method is searched for a lexically enclosing `try` statement that encloses the point of the call to the current method. This search continues until a `catch` clause is found that can handle the current exception, by naming an exception class that is of the same class, or a base class, of the run-time type of the exception being thrown. A `catch` clause that doesn’t name an exception class can handle any exception. +When an exception is thrown ([§22.2](exceptions.md#222-causes-of-exceptions)), the system searches for the nearest catch clause that can handle the exception, as determined by the run-time type of the exception. First, the current method is searched for a lexically enclosing `try` statement, and the associated `catch` clauses of the `try` statement are considered in order. If that fails, the method that called the current method is searched for a lexically enclosing `try` statement that encloses the point of the call to the current method. This search continues until a `catch` clause is found that can handle the current exception, by naming an exception class that is of the same class, or a base class, of the run-time type of the exception being thrown. A `catch` clause that does not name an exception class can handle any exception. Once a matching `catch` clause is found, the system prepares to transfer control to the first statement of the `catch` clause. Before execution of the `catch` clause begins, the system first executes, in order, any `finally` clauses that were associated with `try` statements more nested that than the one that caught the exception. diff --git a/standard/expressions.md b/standard/expressions.md index ce868655b..3cf1840a3 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -1901,7 +1901,7 @@ warning and may inform any ongoing analysis. > Person? p = Find("John"); // returns Person? > if (IsValid(p)) > { -> Console.WriteLine($"Found {p!.Name}"); // p can't be null +> Console.WriteLine($"Found {p!.Name}"); // p cannot be null > } > } > @@ -3773,7 +3773,7 @@ To resolve *cast_expression* ambiguities, the following rule exists: A sequence The term “correct grammar” above means only that the sequence of tokens shall conform to the particular grammatical production. It specifically does not consider the actual meaning of any constituent identifiers. -> *Example*: If `x` and `y` are identifiers, then `x.y` is correct grammar for a type, even if `x.y` doesn’t actually denote a type. *end example* +> *Example*: If `x` and `y` are identifiers, then `x.y` is correct grammar for a type, even if `x.y` does not actually denote a type. *end example* @@ -6773,7 +6773,7 @@ The type of a simple assignment `x = y` is the type of an assignment to `x` of ` The run-time processing of a simple assignment of the form `x = y` with type `T` is performed as an assignment to `x` of `y` with type `T`, which consists of the following recursive steps: -- `x` is evaluated if it wasn’t already. +- `x` is evaluated if it was not already. - If `x` is classified as a variable, `y` is evaluated and, if required, converted to `T` through an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)). - If the variable given by `x` is an array element of a *reference_type*, a run-time check is performed to ensure that the value computed for `y` is compatible with the array instance of which `x` is an element. The check succeeds if `y` is `null`, or if an implicit reference conversion ([§10.2.8](conversions.md#1028-implicit-reference-conversions)) exists from the type of the instance referenced by `y` to the actual element type of the array instance containing `x`. Otherwise, a `System.ArrayTypeMismatchException` is thrown. - The value resulting from the evaluation and conversion of `y` is stored into the location given by the evaluation of `x`, and is yielded as a result of the assignment. @@ -6940,7 +6940,7 @@ The ref assignment operator shall not read the storage location referenced by th -> *Note*: When reading code using an `= ref` operator, it can be tempting to read the `ref` part as being part of the operand. This is particularly confusing when the operand is a conditional `?:` expression. For example, when reading `ref int a = ref b ? ref x : ref y;` it’s important to read this as `= ref` being the operator, and `b ? ref x : ref y` being the right operand: `ref int a = ref (b ? ref x : ref y);`. Importantly, the expression `ref b` is *not* part of that statement, even though it might appear so at first glance. *end note* +> *Note*: When reading code using an `= ref` operator, it can be tempting to read the `ref` part as being part of the operand. This is particularly confusing when the operand is a conditional `?:` expression. For example, when reading `ref int a = ref b ? ref x : ref y;` it is important to read this as `= ref` being the operator, and `b ? ref x : ref y` being the right operand: `ref int a = ref (b ? ref x : ref y);`. Importantly, the expression `ref b` is *not* part of that statement, even though it might appear so at first glance. *end note* ### 12.23.4 Compound assignment diff --git a/standard/interfaces.md b/standard/interfaces.md index d24b73e1c..0b7201a24 100644 --- a/standard/interfaces.md +++ b/standard/interfaces.md @@ -249,13 +249,13 @@ Some declarations, such as *constant_declaration* ([§15.4](classes.md#154-const The inherited members of an interface are specifically not part of the declaration space of the interface. Thus, an interface is allowed to declare a member with the same name or signature as an inherited member. When this occurs, the derived interface member is said to *hide* the base interface member. Hiding an inherited member is not considered an error, but it does result in a warning ([§7.7.2.3](basic-concepts.md#7723-hiding-through-inheritance)). -If a `new` modifier is included in a declaration that doesn’t hide an inherited member, a warning is issued to that effect. +If a `new` modifier is included in a declaration that does not hide an inherited member, a warning is issued to that effect. > *Note*: The members in class `object` are not, strictly speaking, members of any interface ([§19.4](interfaces.md#194-interface-members)). However, the members in class `object` are available via member lookup in any interface type ([§12.5](expressions.md#125-member-lookup)). *end note* The set of members of an interface declared in multiple parts ([§15.2.7](classes.md#1527-partial-type-declarations)) is the union of the members declared in each part. The bodies of all parts of the interface declaration share the same declaration space ([§7.3](basic-concepts.md#73-declarations)), and the scope of each member ([§7.7](basic-concepts.md#77-scopes)) extends to the bodies of all the parts. -> *Example*: Consider an interface `IA` with an implementation for a member `M` and a property `P`. An implementing type `C` doesn’t provide an implementation for either `M` or `P`. They must be accessed through a reference whose compile-time type is an interface that is implicitly convertible to `IA` or `IB`. These members aren’t found through member lookup on a variable of type `C`. +> *Example*: Consider an interface `IA` with an implementation for a member `M` and a property `P`. An implementing type `C` does not provide an implementation for either `M` or `P`. They must be accessed through a reference whose compile-time type is an interface that is implicitly convertible to `IA` or `IB`. These members are not found through member lookup on a variable of type `C`. > > > ```csharp @@ -406,7 +406,7 @@ These rules ensure that any covariant or contravariant usage of the interface re -> *Note*: See [§19.4.2](interfaces.md#1942-interface-fields) for an example that not only shows a static method with an implementation, but as that method is called `Main` and has the right return type and signature, it’s also an entry point. *end note* +> *Note*: See [§19.4.2](interfaces.md#1942-interface-fields) for an example that not only shows a static method with an implementation, but as that method is called `Main` and has the right return type and signature, it is also an entry point. *end note* A virtual method with implementation declared in an interface may be overridden to be abstract in a derived interface. This is known as ***reabstraction***. @@ -562,7 +562,7 @@ Interface members are accessed through member access ([§12.8.7](expressions.md# In a class `D`, with direct or indirect base class `B`, where `B` directly or indirectly implements interface `I` and `I` defines a method `M()`, the expression `base.M()` is valid only if `base.M()` staticly ([§12.3](expressions.md#123-static-and-dynamic-binding)) binds to an implementation of `M()` in a class type. -For interfaces that are strictly single-inheritance (each interface in the inheritance chain has exactly zero or one direct base interface), the effects of the member lookup ([§12.5](expressions.md#125-member-lookup)), method invocation ([§12.8.10.2](expressions.md#128102-method-invocations)), and indexer access ([§12.8.12.4](expressions.md#128124-indexer-access)) rules are exactly the same as for classes and structs: More derived members hide less derived members with the same name or signature. However, for multiple-inheritance interfaces, ambiguities can occur when two or more unrelated base interfaces declare members with the same name or signature. This subclause shows several examples, some of which lead to ambiguities and others which don’t. In all cases, explicit casts can be used to resolve the ambiguities. +For interfaces that are strictly single-inheritance (each interface in the inheritance chain has exactly zero or one direct base interface), the effects of the member lookup ([§12.5](expressions.md#125-member-lookup)), method invocation ([§12.8.10.2](expressions.md#128102-method-invocations)), and indexer access ([§12.8.12.4](expressions.md#128124-indexer-access)) rules are exactly the same as for classes and structs: More derived members hide less derived members with the same name or signature. However, for multiple-inheritance interfaces, ambiguities can occur when two or more unrelated base interfaces declare members with the same name or signature. This subclause shows several examples, some of which lead to ambiguities and others which do not. In all cases, explicit casts can be used to resolve the ambiguities. > *Example*: In the following code > @@ -745,7 +745,7 @@ A class or struct `C` that implements an interface `I` must provide or inherit a > > *end example* -A class or struct that directly implements an interface also implicitly implements all of the interface’s base interfaces. This is true even if the class or struct doesn’t explicitly list all base interfaces in the base class list. +A class or struct that directly implements an interface also implicitly implements all of the interface’s base interfaces. This is true even if the class or struct does not explicitly list all base interfaces in the base class list. > *Example*: > @@ -841,7 +841,7 @@ A derived interface member that satisfies interface mapping ([§19.6.5](interfac > > public void Close() > { -> // Do what's necessary to close the file +> // Do what is necessary to close the file > System.GC.SuppressFinalize(this); > } > } @@ -1391,7 +1391,7 @@ A re-implementation of an interface follows exactly the same interface mapping r > } > ``` > -> the fact that `Control` maps `IControl.Paint` onto `Control.IControl.Paint` doesn’t affect the re-implementation in `MyControl`, which maps `IControl.Paint` onto `MyControl.Paint`. +> the fact that `Control` maps `IControl.Paint` onto `Control.IControl.Paint` does not affect the re-implementation in `MyControl`, which maps `IControl.Paint` onto `MyControl.Paint`. > > *end example* diff --git a/standard/patterns.md b/standard/patterns.md index e224a6caf..82b976fe5 100644 --- a/standard/patterns.md +++ b/standard/patterns.md @@ -45,7 +45,7 @@ Each pattern form defines the set of types for input values that the pattern may > } > ``` > -> However, the following doesn’t generate a compile-time error because the compile-time type of `v` is `object`. A variable of type `object` could have a value that is reference-compatible with `string`: +> However, the following does not generate a compile-time error because the compile-time type of `v` is `object`. A variable of type `object` could have a value that is reference-compatible with `string`: > > > ```csharp @@ -86,7 +86,7 @@ A *simple_designation* with the token `_` shall be considered a *discard_designa The runtime type of the value is tested against the *type* in the pattern using the same rules specified in the is-type operator ([§12.14.12.1](expressions.md#1214121-the-is-type-operator)). If the test succeeds, the pattern *matches* that value. It is a compile-time error if the *type* is a nullable value type ([§8.3.12](types.md#8312-nullable-value-types)) or a nullable reference type ([§8.9.3](types.md#893-nullable-reference-types)). This pattern form never matches a `null` value. -> *Note*: The is-type expression `e is T` and the declaration pattern `e is T _` are equivalent when `T` isn’t a nullable type. *end note* +> *Note*: The is-type expression `e is T` and the declaration pattern `e is T _` are equivalent when `T` is not a nullable type. *end note* Given a pattern input value ([§11.1](patterns.md#111-general)) *e*, if the *simple_designation* is *discard_designation*, it denotes a discard ([§9.2.9.2](variables.md#9292-discards)), and the value of *e* is not bound to anything. (Although a declared variable with the name `_` may be in scope at that point, that named variable is not seen in this context.) Otherwise, if the *simple_designation* is *single_variable_designation*, a local variable ([§9.2.9](variables.md#929-local-variables)) of the given type named by the given identifier is introduced. That local variable is assigned the value of the pattern input value when the pattern *matches* the value. @@ -403,7 +403,7 @@ It is a compile-time error to use a discard pattern in a *relational_expression* > 0.0 > ``` > -> Here, a discard pattern is used to handle `null` and any integer value that doesn’t have the corresponding member of the `DayOfWeek` enumeration. That guarantees that the `switch` expression handles all possible input values. +> Here, a discard pattern is used to handle `null` and any integer value that does not have the corresponding member of the `DayOfWeek` enumeration. That guarantees that the `switch` expression handles all possible input values. > *end example* ## 11.3 Pattern subsumption diff --git a/standard/statements.md b/standard/statements.md index 925564544..bd4f06f5b 100644 --- a/standard/statements.md +++ b/standard/statements.md @@ -562,7 +562,7 @@ Unless specified otherwise below, the semantics of all grammar elements is the s The *identifier* of a *local_function_declaration* shall be unique in its declared block scope, including any enclosing local variable declaration spaces. One consequence of this is that overloaded *local_function_declaration*s are not allowed. -A *local_function_declaration* may include one `async` ([§15.14](classes.md#1514-async-functions)) modifier and one `unsafe` ([§24.1](unsafe-code.md#241-general)) modifier. If the declaration includes the `async` modifier then the return type shall be `void` or a `«TaskType»` type ([§15.14.1](classes.md#15141-general)). If the declaration includes the `static` modifier, the function is a ***static local function***; otherwise, it is a ***non-static local function***. It is a compile-time error for *type_parameter_list* or *parameter_list* to contain *attributes*. If the local function is declared in an unsafe context ([§24.2](unsafe-code.md#242-unsafe-contexts)), the local function may include unsafe code, even if the local function declaration doesn’t include the `unsafe` modifier. +A *local_function_declaration* may include one `async` ([§15.14](classes.md#1514-async-functions)) modifier and one `unsafe` ([§24.1](unsafe-code.md#241-general)) modifier. If the declaration includes the `async` modifier then the return type shall be `void` or a `«TaskType»` type ([§15.14.1](classes.md#15141-general)). If the declaration includes the `static` modifier, the function is a ***static local function***; otherwise, it is a ***non-static local function***. It is a compile-time error for *type_parameter_list* or *parameter_list* to contain *attributes*. If the local function is declared in an unsafe context ([§24.2](unsafe-code.md#242-unsafe-contexts)), the local function may include unsafe code, even if the local function declaration does not include the `unsafe` modifier. A local function is declared at block scope. A non-static local function may capture variables from the enclosing scope while a static local function shall not (so it has no access to enclosing locals, parameters, non-static local functions, or `this`). It is a compile-time error if a captured variable is read by the body of a non-static local function but is not definitely assigned before each call to the function. A compiler shall determine which variables are definitely assigned on return ([§9.4.4.33](variables.md#94433-rules-for-variables-in-local-functions)). @@ -578,7 +578,7 @@ It is a compile-time error for a local function to declare a parameter, type par Local function bodies are always reachable. The endpoint of a local function declaration is reachable if the beginning point of the local function declaration is reachable. -> *Example*: In the following example, the body of `L` is reachable even though the beginning point of `L` is not reachable. Because the beginning point of `L` isn’t reachable, the statement following the endpoint of `L` is not reachable: +> *Example*: In the following example, the body of `L` is reachable even though the beginning point of `L` is not reachable. Because the beginning point of `L` is not reachable, the statement following the endpoint of `L` is not reachable: > > > ```csharp @@ -601,7 +601,7 @@ Local function bodies are always reachable. The endpoint of a local function dec > } > ``` > -> In other words, the location of a local function declaration doesn’t affect the reachability of any statements in the containing function. *end example* +> In other words, the location of a local function declaration does not affect the reachability of any statements in the containing function. *end example* If the type of the argument to a local function is `dynamic`, the function to be called shall be resolved at compile time, not runtime. @@ -1425,7 +1425,7 @@ The body of the `finally` block is constructed according to the following steps: The local variable `d` is not visible to or accessible to any user code. In particular, it does not conflict with any other variable whose scope includes the `finally` block. -> *Note*: An `await foreach` is not required to dispose of `e` synchronously if an asynchronous dispose mechanism isn’t available. *end note* +> *Note*: An `await foreach` is not required to dispose of `e` synchronously if an asynchronous dispose mechanism is not available. *end note* ## 13.10 Jump statements diff --git a/standard/structs.md b/standard/structs.md index 249266ce1..db4b00780 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -228,7 +228,7 @@ All struct types implicitly inherit from the class `System.ValueType`, which, in Struct types are never abstract and are always implicitly sealed. The `abstract` and `sealed` modifiers are therefore not permitted in a struct declaration. -Since inheritance isn’t supported for structs, the declared accessibility of a struct member cannot be `protected`, `private protected`, or `protected internal`. +Since inheritance is not supported for structs, the declared accessibility of a struct member cannot be `protected`, `private protected`, or `protected internal`. Function members in a struct cannot be abstract or virtual, and the `override` modifier is allowed only to override methods inherited from `System.ValueType`. diff --git a/standard/types.md b/standard/types.md index 865f99dfb..5295c3fcc 100644 --- a/standard/types.md +++ b/standard/types.md @@ -510,7 +510,7 @@ When a *namespace_or_type_name* is evaluated, only generic types with the correc > > *end example* -The detailed rules for name lookup in the *namespace_or_type_name* productions is described in [§7.8](basic-concepts.md#78-namespace-and-type-names). The resolution of ambiguities in these productions is described in [§6.2.5](lexical-structure.md#625-grammar-ambiguities). A *type_name* might identify a constructed type even though it doesn’t specify type parameters directly. This can occur where a type is nested within a generic `class` declaration, and the instance type of the containing declaration is implicitly used for name lookup ([§15.3.9.7](classes.md#15397-nested-types-in-generic-classes)). +The detailed rules for name lookup in the *namespace_or_type_name* productions is described in [§7.8](basic-concepts.md#78-namespace-and-type-names). The resolution of ambiguities in these productions is described in [§6.2.5](lexical-structure.md#625-grammar-ambiguities). A *type_name* might identify a constructed type even though it does not specify type parameters directly. This can occur where a type is nested within a generic `class` declaration, and the instance type of the containing declaration is implicitly used for name lookup ([§15.3.9.7](classes.md#15397-nested-types-in-generic-classes)). > *Example*: > @@ -543,7 +543,7 @@ type_argument ; ``` -Each type argument shall satisfy any constraints on the corresponding type parameter ([§15.2.5](classes.md#1525-type-parameter-constraints)). A reference type argument whose nullability doesn’t match the nullability of the type parameter satisfies the constraint; however a warning may be issued. +Each type argument shall satisfy any constraints on the corresponding type parameter ([§15.2.5](classes.md#1525-type-parameter-constraints)). A reference type argument whose nullability does not match the nullability of the type parameter satisfies the constraint; however a warning may be issued. ### 8.4.3 Open and closed types @@ -847,7 +847,7 @@ When the nullable context is ***enabled***: - For any reference type `T`, the annotation `?` in `T?` makes `T?` a nullable type, whereas the unannotated `T` is non-nullable. - A compiler can use static flow analysis to determine the null state of any reference variable. When nullable warnings are enabled, a reference variable’s null state ([§8.9.5](types.md#895-nullabilities-and-null-states)) is either *not null*, *maybe null*, or *maybe default* and - The null-forgiving operator `!` ([§12.8.9](expressions.md#1289-null-forgiving-expressions)) sets the null state of its operand to *not null*. -- A compiler can issue a warning if the nullability of a type parameter doesn’t match the nullability of its corresponding type argument. +- A compiler can issue a warning if the nullability of a type parameter does not match the nullability of its corresponding type argument. ### 8.9.5 Nullabilities and null states @@ -990,7 +990,7 @@ Both auto-property and field-like event declarations make use of a compiler-gene > } > ``` > -> In the previous example, the constructor doesn’t set `P` to a not null value, and a compiler may issue a warning. There’s no warning when the `P` property is accessed, because the type of the property is a non nullable reference type. *end example* +> In the previous example, the constructor does not set `P` to a not null value, and a compiler may issue a warning. There is no warning when the `P` property is accessed, because the type of the property is a non nullable reference type. *end example* A compiler can treat a property ([§15.7](classes.md#157-properties)) as either a variable with state, or as independent get and set accessors ([§15.7.3](classes.md#1573-accessors)). @@ -1027,7 +1027,7 @@ A compiler can treat a property ([§15.7](classes.md#157-properties)) as either > } > ``` > -> In the previous example, the backing field for the `DisappearingProperty` is set to null when it is read. However, a compiler may assume that reading a property doesn’t change the null state of that expression. *end example* +> In the previous example, the backing field for the `DisappearingProperty` is set to null when it is read. However, a compiler may assume that reading a property does not change the null state of that expression. *end example* A compiler may use any expression that dereferences a variable, property, or event to set the null state to not null. If it were null, the dereference expression would have thrown a `NullReferenceException`: diff --git a/standard/unsafe-code.md b/standard/unsafe-code.md index 053cafdff..1929d0dd7 100644 --- a/standard/unsafe-code.md +++ b/standard/unsafe-code.md @@ -12,7 +12,7 @@ An implementation that does not support unsafe code is required to diagnose any > > In unsafe code, it is possible to declare and operate on pointers, to perform conversions between pointers and integral types, to take the address of variables, and so forth. In a sense, writing unsafe code is much like writing C code within a C# program. > -> Unsafe code is in fact a “safe” feature from the perspective of both developers and users. Unsafe code shall be clearly marked with the modifier `unsafe`, so developers can’t possibly use unsafe features accidentally, and the execution engine works to ensure that unsafe code cannot be executed in an untrusted environment. +> Unsafe code is in fact a “safe” feature from the perspective of both developers and users. Unsafe code shall be clearly marked with the modifier `unsafe`, so developers cannot possibly use unsafe features accidentally, and the execution engine works to ensure that unsafe code cannot be executed in an untrusted environment. > > *end note* @@ -400,7 +400,7 @@ pointer_indirection_expression ; ``` -The unary `*` operator denotes pointer indirection and is used to obtain the variable to which a pointer points. The result of evaluating `*P`, where `P` is an expression of a pointer type `T*`, is a variable of type `T`. It is a compile-time error to apply the unary `*` operator to an expression of type `void*` or to an expression that isn’t of a pointer type. +The unary `*` operator denotes pointer indirection and is used to obtain the variable to which a pointer points. The result of evaluating `*P`, where `P` is an expression of a pointer type `T*`, is a variable of type `T`. It is a compile-time error to apply the unary `*` operator to an expression of type `void*` or to an expression that is not of a pointer type. The effect of applying the unary `*` operator to a `null`-valued pointer is implementation-defined. In particular, there is no guarantee that this operation throws a `System.NullReferenceException`. @@ -717,7 +717,7 @@ It is the programmer’s responsibility to ensure that pointers created by fixed > *Example*: When pointers created by `fixed` statements are passed to external APIs, it is the programmer’s responsibility to ensure that the APIs retain no memory of these pointers. *end example* -Fixed objects can cause fragmentation of the heap (because they can’t be moved). For that reason, objects should be fixed only when absolutely necessary and then only for the shortest amount of time possible. +Fixed objects can cause fragmentation of the heap (because they cannot be moved). For that reason, objects should be fixed only when absolutely necessary and then only for the shortest amount of time possible. > *Example*: The example > @@ -1065,7 +1065,7 @@ When a *stackalloc_expression* occurs as the initializing expression of a *local > int* p2 = stackalloc int[3] { -10, -15, -30 }; > // Type int is inferred > int* p3 = stackalloc[] { 11, 12, 13 }; -> // Can't infer context, so pointer result assumed +> // Cannot infer context, so pointer result assumed > var p4 = stackalloc[] { 11, 12, 13 }; > // Error; no conversion exists > long* p5 = stackalloc[] { 11, 12, 13 }; diff --git a/standard/variables.md b/standard/variables.md index e5b3d435f..5191acd83 100644 --- a/standard/variables.md +++ b/standard/variables.md @@ -278,7 +278,7 @@ The body of a function member may declare one or more initially unassigned varia The definite-assignment state of *v* can be either: - Definitely assigned. This indicates that on all possible control flows to this point, *v* has been assigned a value. -- Not definitely assigned. For the state of a variable at the end of an expression of type `bool`, the state of a variable that isn’t definitely assigned might (but doesn’t necessarily) fall into one of the following sub-states: +- Not definitely assigned. For the state of a variable at the end of an expression of type `bool`, the state of a variable that is not definitely assigned might (but does not necessarily) fall into one of the following sub-states: - Definitely assigned after true expression. This state indicates that *v* is definitely assigned if the Boolean expression evaluated as true, but is not necessarily assigned if the Boolean expression evaluated as false. - Definitely assigned after false expression. This state indicates that *v* is definitely assigned if the Boolean expression evaluated as false, but is not necessarily assigned if the Boolean expression evaluated as true. @@ -1115,7 +1115,7 @@ These values form a nesting relationship from narrowest (declaration-block) to w > // ref safe context is "function-member" > public ref int M2(int v1) > { -> return ref v1; // error: v1 isn't safe to ref return +> return ref v1; // error: v1 is not safe to ref return > } > > public ref int M3() @@ -1184,7 +1184,7 @@ For a local variable `v`: For a parameter `p`: -- If `p` is a reference or input parameter, its ref-safe-context is the caller-context. If `p` is an input parameter, it can’t be returned as a writable `ref` but can be returned as `ref readonly`. +- If `p` is a reference or input parameter, its ref-safe-context is the caller-context. If `p` is an input parameter, it cannot be returned as a writable `ref` but can be returned as `ref readonly`. - If `p` is an output parameter, its ref-safe-context is the caller-context. - Otherwise, if `p` is the `this` parameter of a struct type, its ref-safe-context is the function-member. - Otherwise, the parameter is a value parameter, and its ref-safe-context is the function-member.