@@ -859,6 +859,8 @@ A compiler is not required to perform any static analysis nor is it required to
859
859
860
860
**The remainder of this subclause is conditionally normative .**
861
861
862
+ #### 8.9.5.1 Flow analysis
863
+
862
864
A compiler that generates diagnostic warnings conforms to these rules .
863
865
864
866
Every expression has one of three ***null state ***s :
@@ -1042,4 +1044,123 @@ A compiler may use any expression that dereferences a variable, property, or eve
1042
1044
>
1043
1045
> * end example *
1044
1046
1047
+ #### 8.9.5.2 Type conversions
1048
+
1049
+ A compiler that generates diagnostic warnings conforms to these rules .
1050
+
1051
+ > * Note : * Differences in top - level or nested nullability annotations in types do not affect whether conversion between the types is permitted , since there is no semantic difference between a non -nullable reference type and its corresponding nullable type ([§8.9.1 ](types .md #891-general )).
1052
+
1053
+ A compiler may issue a warning when nullability annotations differ between two types , either top - level or nested , when the conversion is narrowing .
1054
+
1055
+ > *Example *: Types differing in top - level annotations
1056
+ >
1057
+ > < ! -- Example : {template : " code-in-class-lib" , name : " TopLevelNullabilityConversionWarnings" } -- >
1058
+ > ```csharp
1059
+ > #nullable enable
1060
+ > public class C
1061
+ > {
1062
+ > public void M1 (string p )
1063
+ > {
1064
+ > _ = (string ?)p ; // No warning, widening
1065
+ > }
1066
+ >
1067
+ > public void M2 (string ? p )
1068
+ > {
1069
+ > _ = (string )p ; // Warning, narrowing
1070
+ > _ = (string )p ! ; // No warning, suppressed
1071
+ > }
1072
+ > }
1073
+ > ```
1074
+ >
1075
+ > * end example *
1076
+
1077
+ > * Example * : Types differing in nested nullability annotations
1078
+ >
1079
+ > < ! -- Example : {template : " code-in-class-lib" , name : " NestedNullabilityConversionWarnings" } -- >
1080
+ > ```csharp
1081
+ > #nullable enable
1082
+ > public class C
1083
+ > {
1084
+ > public void M1 ((string , string ) p )
1085
+ > {
1086
+ > _ = ((string ?, string ?))p ; // No warning, widening
1087
+ > }
1088
+ >
1089
+ > public void M2 ((string ? , string ? ) p )
1090
+ > {
1091
+ > _ = ((string , string ))p ; // Warning, narrowing
1092
+ > _ = ((string , string ))p ! ; // No warning, suppressed
1093
+ > }
1094
+ > }
1095
+ > ```
1096
+ >
1097
+ > * end example *
1098
+
1099
+ A compiler may follow rules for interface variance ([§18.2.3.3](interfaces.md#18233-variance-conversion)), delegate variance ([§20.4](delegates.md#204-delegate-compatibility)), and array covariance ([§1.7.6 ](arrays .md #176 - array - covariance )) in determining whether to issue a warning for type conversions.
1100
+
1101
+ > <!-- Example: {template:"code-in-class-lib", name:"NullVariance"} -- >
1102
+ > ```csharp
1103
+ > #nullable enable
1104
+ > public class C
1105
+ > {
1106
+ > public void M1 (IEnumerable <string > p )
1107
+ > {
1108
+ > IEnumerable < string ? > v1 = p ; // No warning
1109
+ > }
1110
+ >
1111
+ > public void M2 (IEnumerable <string ?> p )
1112
+ > {
1113
+ > IEnumerable < string > v1 = p ; // Warning
1114
+ > IEnumerable < string > v2 = p ! ; // No warning
1115
+ > }
1116
+ >
1117
+ > public void M3 (Action <string ?> p )
1118
+ > {
1119
+ > Action < string > v1 = p ; // No warning
1120
+ > }
1121
+ >
1122
+ > public void M4 (Action <string > p )
1123
+ > {
1124
+ > Action < string ? > v1 = p ; // Warning
1125
+ > Action < string ? > v2 = p ! ; // No warning
1126
+ > }
1127
+ >
1128
+ > public void M5 (string [] p )
1129
+ > {
1130
+ > string ? [] v1 = p ; // No warning
1131
+ > }
1132
+ >
1133
+ > public void M6 (string ?[] p )
1134
+ > {
1135
+ > string [] v1 = p ; // Warning
1136
+ > string [] v2 = p ! ; // No warning
1137
+ > }
1138
+ > }
1139
+ > ```
1140
+ >
1141
+ > * end example *
1142
+
1143
+ A compiler may issue a warning when nullability differs in either direction in types which do not permit a variant conversion .
1144
+
1145
+ > < ! -- Example : {template : " code-in-class-lib" , name : " NullInvariance" } -- >
1146
+ > ```csharp
1147
+ > #nullable enable
1148
+ > public class C
1149
+ > {
1150
+ > public void M1 (List < string > p )
1151
+ > {
1152
+ > List < string ? > v1 = p ; // Warning
1153
+ > List < string ? > v1 = p ! ; // No Warning
1154
+ > }
1155
+ >
1156
+ > public void M2 (List < string ? > p )
1157
+ > {
1158
+ > List < string > v1 = p ; // Warning
1159
+ > List < string > v1 = p ! ; // No Warning
1160
+ > }
1161
+ > }
1162
+ > ```
1163
+ >
1164
+ > * end example *
1165
+
1045
1166
*** End of conditionally normative text ***
0 commit comments