Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the list of attributes that support nullable analysis. #1191

Open
wants to merge 14 commits into
base: draft-v8
Choose a base branch
from
30 changes: 15 additions & 15 deletions standard/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -860,11 +860,11 @@ For invocations that occur within field or event initializers, the member name u

For invocations that occur within declarations of instance constructors, static constructors, finalizers and operators the member name used is implementation-dependent.

### §Nullable-Analysis-Attributes Code analysis-attributes
### §Nullable-Analysis-Attributes Code analysis attributes

#### §Nullable-Analysis-Attributes-General General

The attributes in this section are used to provide additional information to support a compiler that provides nullability and null-state diagnostics (§8.9.5). 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 meaning of the attributes defined in this section.
The attributes in this section are used to provide additional information to support a compiler that provides nullability and null-state diagnostics (§8.9.5). 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 section for any of these attributes which it uses to inform its diagnostics.

The code-analysis attributes are declared in namespace `System.Diagnostics.CodeAnalysis`.

Expand Down Expand Up @@ -953,13 +953,13 @@ Specifies that a given method never returns.
> private void FailFast() =>
> throw new InvalidOperationException();
>
> public void SetState(object containedField)
> public void SetState(object? containedField)
> {
> if (!isInitialized)
> if ((!isInitialized) || (containedField == null))
> {
> FailFast();
> // unreachable code when not initialized:
> }
> // null check not needed.
> _field = containedField;
> }
>
Expand All @@ -976,22 +976,22 @@ Specifies that a given method never returns if the associated `bool` parameter h

> *Example*: Consider the following:
>
> <!-- Example: {template:"standalone-lib", name:"DoesNotReturnIfAttribute"} -->
> <!-- Example: {template:"standalone-lib", name:"DoesNotReturnIfAttribute", expectedWarnings:["CS0414"]} -->
> ```csharp
> #nullable enable
> public class X
> {
> private void FailFastIf([DoesNotReturnIf(false)] bool isValid)
> private void ThrowIfNull([DoesNotReturnIf(true)] bool isNull, string argumentName)
> {
> if (!isValid)
> if (!isNull)
> {
> throw new InvalidOperationException();
> throw new ArgumentException(argumentName, $"argument {argumentName} can't be null");
> }
> }
>
> public void SetFieldState(object containedField)
> {
> FailFastIf(isInitialized);
> ThrowIfNull(containedField == null, nameof(containedField));
> // unreachable code when "isInitialized" is false:
> _field = containedField;
> }
Expand Down Expand Up @@ -1028,15 +1028,15 @@ Specifies that a non-nullable return value may be null.

#### §The-MaybeNullWhen-Attribute The MaybeNullWhen attribute

Specifies that a non-nullable argument may be `null` when the method returns the specified `bool` value. This is similar to the `MaybeNull` attribute (§The-MaybeNull-Attribute), but include a parameter for the specified return value.
Specifies that a non-nullable argument may be `null` when the method returns the specified `bool` value. This is similar to the `MaybeNull` attribute (§The-MaybeNull-Attribute), but includes a parameter for the specified return value.

#### §The-MemberNotNull-Attribute The MemberNotNull attribute

Specifies that the given member won't be `null` when the method returns.

> *Example*: The compiler may analyze constructors and field initializers to make sure that all non-nullable reference fields have been initialized before each constructor returns. However, the compiler doesn't track field assignments through called helper methods. The `MemberNotNull` attribute specifies the fields that are initialized to a non-null value in that method. For example, consider the following example:
> *Example*: A helper method adds the `MemberNotNull` attribute to specify any fields that are assigned to a non-null value in that method. A compiler that analyzes constructors to make sure that all non-nullable reference fields have been initialized uses this attribute to determine that fields have been set in those helper methods. Consider the following example:
BillWagner marked this conversation as resolved.
Show resolved Hide resolved
>
> <!-- Example: {template:"standalone-lib", name:"MemeberNotNullAttribute"} -->
> <!-- Example: {template:"standalone-lib", name:"MemberNotNullAttribute"} -->
> ```csharp
> #nullable enable
> public class Container
Expand Down Expand Up @@ -1096,15 +1096,15 @@ Specifies that a nullable return value will never be `null`.

Specifies that a return value isn't `null` if the argument for the specified parameter isn't `null`.

> *Example*: The null state of a return value may depend on the null state of one or more arguments. Such a method will return a non-null value when certain arguments aren't `null`. To correctly annotate these methods, add the `NotNullIfNotNull` attribute. Consider the following method:
> *Example*: The null state of a return value could depend on the null state of one or more arguments. Such a method always returns a non-null value when certain arguments aren't `null`. To assist the compiler with analyzing such methods the `NotNullIfNotNull` attribute may be used. Consider the following method:
BillWagner marked this conversation as resolved.
Show resolved Hide resolved
>
> <!-- Example: {template:"code-in-class-lib", name:"NotNullIfNotNull1Attribute", replaceEllipsis:true, customEllipsisReplacements: ["return \"\";"]} -->
> ```csharp
> #nullable enable
> 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 return value could also be null. To express that contract correctly, annotate this method as follows:
> 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:
>
> <!-- Example: {template:"code-in-class-lib", name:"NotNullIfNotNull2Attribute", replaceEllipsis:true, customEllipsisReplacements: ["return \"\";"]} -->
> ```csharp
Expand Down
Loading