Skip to content

Commit 06e6d7e

Browse files
committed
Draft grammar to permit nullable types as array element types.
1 parent cd3310a commit 06e6d7e

File tree

5 files changed

+47
-3
lines changed

5 files changed

+47
-3
lines changed

standard/arrays.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@ In effect, the *rank_specifier*s are read from left to right *before* the final
4646
4747
> *Example*: The type in `T[][,,][,]` is a single-dimensional array of three-dimensional arrays of two-dimensional arrays of `int`. *end example*
4848
49-
At run-time, a value of an array type can be `null` or a reference to an instance of that array type.
50-
51-
> *Note*: Following the rules of17.6](arrays.md#176-array-covariance), the value may also be a reference to a covariant array type. *end note*
49+
At run-time, a value of an array type can be:
50+
- `null`; or
51+
- a reference to an instance of that array type; or
52+
- a reference to an instance of a covariant array type, following the rules of17.6](arrays.md#176-array-covariance).
5253
5354
### 17.2.2 The System.Array type
5455

standard/types.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ non_array_type
6464
| delegate_type
6565
| 'dynamic'
6666
| type_parameter
67+
| nullable_reference_type
6768
| pointer_type // unsafe code support
6869
;
6970
@@ -738,6 +739,8 @@ There are two forms of nullability for reference types:
738739
739740
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.
740741

742+
The only exception to this general rule is that adding a nullable annotation can change the syntactic meaning of the type of an array of arrays. Specifically, a type such as `A[][,]` is an array of two-dimensional arrays. That is because the syntactic meaning of the array dimensions in the array type are read from the inside out. However, by adding a nullable annotation between the dimensions, writing `A[]?[,]`, changes the parsing and therefore syntactic meaning of the type. In this case, the element type of the array is `A[]?`. The type is now a two-dimensional array of a nullable array type.
743+
741744
### 8.9.2 Non-nullable reference types
742745

743746
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.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Sample: Arrays of NRT
2+
3+
Samples for nullable arrays, arrays of nullables, and nullable arrays of nullables.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-ms Rules -rt
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
class ArraysOfNullable
2+
{
3+
class A { }
4+
5+
void ArraysOfNullable()
6+
{
7+
A[] p_1 = new A[5]; // Array of non-nullable A all elements inited to null (oops)
8+
A[]? q_1 = null; // Nullable array of non-nullable A, array inited to null
9+
A?[] r_1 = new A[5]; // Array of nullable A all elements inited to null
10+
A?[]? s_1 = null; // Nullable array of nullable A, array inited to null
11+
12+
string[] p_2 = new string[5]; // Array of non-nullable string all elements inited to null (oops)
13+
string[]? q_2 = null; // Nullable array of non-nullable string, array inited to null
14+
string?[] r_2 = new string[5]; // Array of nullable string all elements inited to null
15+
string?[]? s_2 = null; // Nullable array of nullable string, array inited to null
16+
17+
int[] p_3 = new int[5]; // Array of non-nullable int all elements inited to 0
18+
int[]? q_3 = null; // Nullable array of non-nullable int, array inited to null
19+
int?[] r_3 = new int[5]; // Array of nullable int all elements inited to null
20+
int?[]? s_3 = null; // Nullable array of nullable int, array inited to null
21+
22+
dynamic[] p_4 = new dynamic[5]; // Array of non-nullable dynamic all elements inited to 0
23+
dynamic[]? q_4 = null; // Nullable array of non-nullable dynamic, array inited to null
24+
dynamic?[] r_4 = new dynamic[5]; // Array of nullable dynamic all elements inited to null
25+
dynamic?[]? s_4 = null; // Nullable array of nullable dynamic, array inited to null
26+
27+
A[][,] p_5 = new A[1][1,1]; // Array of two-dimensional array
28+
A[][,]? q_5 = null; // Array of two-dimensional array
29+
A[]?[,] r_5 = new A[]?[1,1]; // Two dimensional array of array
30+
A[]?[,]? s_5 = null; // Two dimensional array of array
31+
A?[][,] t_5 = new A[1][1,1]; // Array of two-dimensional array
32+
A?[][,]? u_5 = null; // Array of two-dimensional array
33+
A?[]?[,] v_5 = new A[]?[1,1]; // Two dimensional array of array
34+
A?[]?[,]? w_5 = null; // Two dimensional array of array
35+
}
36+
}

0 commit comments

Comments
 (0)