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
Copy file name to clipboardExpand all lines: standard/classes.md
+21-14Lines changed: 21 additions & 14 deletions
Original file line number
Diff line number
Diff line change
@@ -412,17 +412,18 @@ type_parameter_constraints
412
412
;
413
413
414
414
primary_constraint
415
-
:class_type
416
-
|'class'
415
+
:class_type'?'?
416
+
|'class''?'?
417
417
|'struct'
418
+
| `notnull`
418
419
|'unmanaged'
419
420
;
420
421
421
422
secondary_constraints
422
-
:interface_type
423
+
:interface_type'?'?
423
424
|type_parameter
424
-
|secondary_constraints','interface_type
425
-
|secondary_constraints','type_parameter
425
+
|secondary_constraints','interface_type'?'?
426
+
|secondary_constraints','type_parameter'?'?
426
427
;
427
428
428
429
constructor_constraint
@@ -434,14 +435,18 @@ Each *type_parameter_constraints_clause* consists of the token `where`, followed
434
435
435
436
The list of constraints given in a `where` clause can include any of the following components, in this order: a single primary constraint, one or more secondary constraints, and the constructor constraint, `new()`.
436
437
437
-
A primary constraint can be a class type, the ***reference type constraint***`class`, the ***value type constraint***`struct`, or the ***unmanaged type constraint***`unmanaged`.
438
+
A primary constraint can be a class type, the ***reference type constraint***`class`, the ***nullable reference type constraint***`class?`, the ***not null*** constraint `notnull`, the ***value type constraint***`struct` or the ***unmanaged type constraint***`unmanaged`.
438
439
439
-
A secondary constraint can be a *type_parameter* or *interface_type*.
440
+
A secondary constraint can be a *type_parameter* or *interface_type*, either optionally followed by `?`.
440
441
441
-
The reference type constraint specifies that a type argument used for the type parameter shall be a reference type. All class types, interface types, delegate types, array types, and type parameters known to be a reference type (as defined below) satisfy this constraint.
442
+
The reference type constraint specifies that a type argument used for the type parameter shall be a non-nullable reference type. All non-nullable class types, non-nullable interface types, non-nullable delegate types, non-nullable array types, and type parameters known to be a non-nullable reference type (as defined below) satisfy this constraint.
443
+
444
+
The nullable reference type constraint specifies that a type argument shall be either a non-nullable reference type or a nullable reference type. All class types, interface types, delegate types, array types, and type parameters known to be a reference type (as defined below) satisfy this constraint.
442
445
443
446
The value type constraint specifies that a type argument used for the type parameter shall be a non-nullable value type. All non-nullable struct types, enum types, and type parameters having the value type constraint satisfy this constraint. Note that although classified as a value type, a nullable value type ([§8.3.12](types.md#8312-nullable-value-types)) does not satisfy the value type constraint. A type parameter having the value type constraint shall not also have the *constructor_constraint*, although it may be used as a type argument for another type parameter with a *constructor_constraint*.
444
447
448
+
The ***not null*** constraint specifies that a type argument used for the type parameter shall be a non-nullable value type or a non-nullable reference type. All non-nullable class types, interface types, delegate types, array types, struct types, enum types, and type parameters known to be a non-nullable value type or non-nullable reference type satisfy this constraint.
449
+
445
450
> *Note*: The `System.Nullable<T>` type specifies the non-nullable value type constraint for `T`. Thus, recursively constructed types of the forms `T??` and `Nullable<Nullable<T>>` are prohibited. *end note*
446
451
447
452
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.
@@ -604,7 +609,9 @@ The ***effective interface set*** of a type parameter `T` is defined as follows
@@ -610,8 +610,20 @@ A type parameter is an identifier designating a value type or reference type tha
610
610
type_parameter
611
611
:identifier
612
612
;
613
+
614
+
nullable_type_parameter
615
+
:non_nullable_non_value_type_parameter'?'
616
+
;
617
+
618
+
non_nullable_non_value_type_parameter
619
+
:type_parameter
620
+
;
613
621
```
614
622
623
+
The *non_nullable_non_value_type_parameter* in *nullable_type_parameter* shall be a type parameter that isn’t constrained to be a value type.
624
+
625
+
In *nullable_type_parameter*, the annotation `?` indicates the intent that type arguments of this type are nullable. The absence of the annotation `?` indicates the intent that type arguments of this type are non-nullable.
626
+
615
627
Since a type parameter can be instantiated with many different type arguments, type parameters have slightly different operations and restrictions than other types.
616
628
617
629
> *Note*: These include:
@@ -714,157 +726,37 @@ An *unmanaged_type* is any type that isn’t a *reference_type*, a *type_paramet
- Any user-defined *struct_type* that is not a constructed type and contains instance fields of *unmanaged_type*s only.
717
-
- In unsafe code ([§23.2](unsafe-code.md#232-unsafe-contexts)), any *pointer_type* ([§23.3](unsafe-code.md#233-pointer-types)).
718
-
719
-
## 8.9 Reference Types and nullability
720
-
721
-
### 8.9.1 General
722
-
723
-
A *nullable reference type* is denoted by appending a `?` to a valid non-nullable reference type name. There is no semantic difference between a non-nullable reference type and its corresponding nullable type. Both a nullable reference and a non-nullable reference can contain either a reference to an object or `null`. The presence or absence of the `?` annotation declares whether an expression is intended to permit null values or not. A compiler can 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)).
724
-
725
-
There are two forms of nullability for reference types:
726
-
727
-
-*nullable*: A *nullable-reference-type* can be assigned `null`. Its default null state is *maybe-null*.
728
-
-*non-nullable*” A *non-nullable reference* should not be assigned a `null` value. Its default null state is *not-null*.
729
-
730
-
> *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*
731
-
732
-
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 `?` 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.
733
-
734
-
### 8.9.2 Non-nullable reference types
735
-
736
-
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.
737
-
738
-
### 8.9.3 Nullable reference types
739
-
740
-
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.
741
-
742
-
### 8.9.4 Nullable context
743
-
744
-
#### 8.9.4.1 General
745
-
746
-
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*.
747
-
748
-
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.
749
-
750
-
The default state of the nullable context is implementation defined.
751
-
752
-
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.
753
-
754
-
> *Note:* A nullable context where both flags are disabled matches the previous standard behavior for reference types. *end note*
755
-
756
-
#### 8.9.4.2 Nullable disable
757
-
758
-
When both the warning and annotations flags are disabled, the nullable context is *disabled*.
759
-
760
-
When the nullable context is ***disabled***:
761
-
762
-
- No warning shall be generated when a variable of an unannotated reference type is initialized with, or assigned a value of, `null`.
763
-
- No warning shall be generated when a variable of a reference type that possibly has the null value.
764
-
- For any reference type `T`, the annotation `?` in `T?` generates a message and the type `T?` is the same as `T`.
765
-
> *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*
766
-
- The null-forgiving operator `!` ([§12.8.9](expressions.md#1289-null-forgiving-expressions)) has no effect.
The distinction between the null states “maybe null” and “maybe default” is subtle and applies to type parameters. A type parameter `T` that has the state “maybe null” means the value is in the domain of valid values for `T`; however, that valid value may include `null`. A “maybe default” state means that the value may be outside the valid domain of values for `T`.
-*maybedefault*:Thevalueoftheexpressionmayevaluatetothedefaultvaluefor that type.
855
-
- *not null*: The value of the expression isn’t null.
856
-
857
-
The ***default null state*** of an expression is determined by its type, and the state of the annotations flag when it is declared:
858
-
859
-
- The default null state of a nullable reference type is:
860
-
- Maybe null when its declaration is in text where the annotations flag is enabled.
861
-
- Not null when its declaration is in text where the annotations flag is disabled.
862
-
- The default null state of a non-nullable reference type is not null.
863
-
864
-
A diagnostic can be produced when a variable ([§9.2.1](variables.md#921-general)) ofanon-nullablereferencetypeisinitializedorassignedtoanexpressionthatismaybenull when that variable is declared in text where the annotation flag is enabled.
When the nullable annotation context is enabled, the compiler shall recognize these intents. When the nullable annotation context is disabled, the compiler shall ignore these intents, thereby treating `T` and `T?` in the same (nullable) manner, and generate a warning. (The latter scenario was the only one that existed prior to the addition of nullable reference types.)
0 commit comments