You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Any user-defined *struct_type* that is not a constructed type and contains instance fields of *unmanaged_type*s only.
723
-
- In unsafe code ([§22.2](unsafe-code.md#222-unsafe-contexts)), any *pointer_type* ([§22.3](unsafe-code.md#223-pointer-types)).
723
+
- In unsafe code ([§23.2](unsafe-code.md#232-unsafe-contexts)), any *pointer_type* ([§23.3](unsafe-code.md#233-pointer-types)).
724
+
725
+
## 8.9 Reference Types and nullability
726
+
727
+
### 8.9.1 General
728
+
729
+
A *nullable reference type* is denoted by appending a *nullable_type_annotation* (`?`) to a non-nullable reference type. There is no semantic difference between a non-nullable reference type and its corresponding nullable type, both can either be a reference to an object or `null`. The presence or absence of the *nullable_type_annotation* declares whether an expression is intended to permit null values or not. A compiler may provide diagnostics when an expression is not used according to that intent. The null state of an expression is defined in [§8.9.5](types.md#895-nullabilities-and-null-states). An identity conversion exists among a nullable reference type and its corresponding non-nullable reference type ([§10.2.2](conversions.md#1022-identity-conversion)).
730
+
731
+
There are two forms of nullability for reference types:
732
+
733
+
-*nullable*: A *nullable-reference-type* can be assigned `null`. Its default null state is *maybe-null*.
734
+
-*non-nullable*: A *non-nullable reference* should not be assigned a `null` value. Its default null state is *not-null*.
735
+
736
+
> *Note:* The types `R` and `R?` are represented by the same underlying type, `R`. A variable of that underlying type can either contain a reference to an object or be the value `null`, which indicates “no reference.” *end note*
737
+
738
+
The syntactic distinction between a *nullable reference type* and its corresponding *non-nullable reference type* enables a compiler to generate diagnostics. A compiler must allow the *nullable_type_annotation* as defined in [§8.2.1](types.md#821-general). The diagnostics must be limited to warnings. Neither the presence or absence of nullable annotations, nor the state of the nullable context can change the compile time or runtime behavior of a program except for changes in any diagnostic messages generated at compile time.
739
+
740
+
### 8.9.2 Non-nullable reference types
741
+
742
+
A ***non-nullable reference type*** is a reference type of the form `T`, where `T` is the name of the type. The default null-state of a non-nullable variable is *not-null*. Warnings may be generated when an expression that is *maybe-null* is used where a *not-null* value is required.
743
+
744
+
### 8.9.3 Nullable reference types
745
+
746
+
A reference type of the form `T?` (such as `string?`) is a ***nullable reference type***. The default null-state of a nullable variable is *maybe null*. The annotation `?` indicates the intent that variables of this type are nullable. The compiler can recognize these intents to issue warnings. When the nullable annotation context is disabled, using this annotation can generate a warning.
747
+
748
+
### 8.9.4 Nullable context
749
+
750
+
#### 8.9.4.1 General
751
+
752
+
Every line of source code has a ***nullable context***. The annotations and warnings flags for the nullable context control nullable annotations ([§8.9.4.3](types.md#8943-nullable-annotations)) and nullable warnings ([§8.9.4.4](types.md#8944-nullable-warnings)), respectively. Each flag can be *enabled* or *disabled*. The compiler can use static flow analysis to determine the null state of any reference variable. 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*.
753
+
754
+
The nullable context may be specified within source code via nullable directives ([§6.5.9](lexical-structure.md#659-nullable-directive)) and/or via some implementation-specific mechanism external to the source code. If both approaches are used, nullable directives supersede the settings made via an external mechanism.
755
+
756
+
The default state of the nullable context is implementation defined.
757
+
758
+
Throughout this specification, all C# code that does not contain nullable directives, or about which no statement is made regarding the current nullable context state, shall be assumed to have been compiled using a nullable context where both annotations and warnings are enabled.
759
+
760
+
> *Note:* A nullable context where both flags are disabled matches the previous standard behavior for reference types. *end note*
761
+
762
+
#### 8.9.4.2 Nullable disable
763
+
764
+
When both the warning and annotations flags are disabled, the nullable context is *disabled*.
765
+
766
+
When the nullable context is ***disabled***:
767
+
768
+
- No warning shall be generated when a variable of an unannotated reference type is initialized with, or assigned a value of, `null`.
769
+
- No warning shall be generated when a variable of a reference type that possibly has the null value.
770
+
- For any reference type `T`, the annotation `?` in `T?` generates a message and the type `T?` is the same as `T`.
771
+
- For any type parameter constraint `where T : C?`, the annotation `?` in `C?` generates a message and the type `C?` is the same as `C`.
772
+
- For any type parameter constraint `where T : U?`, the annotation `?` in `U?` generates a message and the type `U?` is the same as `U`.
773
+
- The generic constraint `class?` generates a warning message. The type parameter must be a reference type.
774
+
> *Note*: This message is characterized as “informational” rather than “warning,” so as not to confuse it with the state of the nullable warning setting, which is unrelated. *end note*
775
+
- The null-forgiving operator `!` ([§12.8.9](expressions.md#1289-null-forgiving-expressions)) has no effect.
-*maybedefault*:Thevalueoftheexpressionmayevaluatetothedefaultvaluefor that type.
867
+
- *not null*: The value of the expression isn’t null.
868
+
869
+
The ***default null state*** of an expression is determined by its type, and the state of the annotations flag when it is declared:
870
+
871
+
- The default null state of a nullable reference type is:
872
+
- Maybe null when its declaration is in text where the annotations flag is enabled.
873
+
- Not null when its declaration is in text where the annotations flag is disabled.
874
+
- The default null state of a non-nullable reference type is not null.
875
+
876
+
> *Note:* The *maybe default* state is used with unconstrained type parameters when the type is a non-nullable type, such as `string` and the expression `default(T)` isthenullvalue. Becausenullisnotinthedomainforthenon-nullabletype, thestateismaybedefault. *endnote*
877
+
878
+
Adiagnosticcanbeproduced when a variable ([§9.2.1](variables.md#921-general)) of a non-nullable reference type is initialized or assigned to an expression that is maybe null when that variable is declared in text where the annotation flag is enabled.
>Inthepreviousexample, thebackingfieldfor 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*
0 commit comments