@@ -219,7 +219,7 @@ Expression ParseConditionalOperator()
219
219
_textParser . ValidateToken ( TokenId . Colon , Res . ColonExpected ) ;
220
220
_textParser . NextToken ( ) ;
221
221
Expression expr2 = ParseConditionalOperator ( ) ;
222
- expr = GenerateConditional ( expr , expr1 , expr2 , errorPos ) ;
222
+ expr = GenerateConditional ( expr , expr1 , expr2 , false , errorPos ) ;
223
223
}
224
224
return expr ;
225
225
}
@@ -1145,7 +1145,7 @@ Expression ParseFunctionIif()
1145
1145
throw ParseError ( errorPos , Res . IifRequiresThreeArgs ) ;
1146
1146
}
1147
1147
1148
- return GenerateConditional ( args [ 0 ] , args [ 1 ] , args [ 2 ] , errorPos ) ;
1148
+ return GenerateConditional ( args [ 0 ] , args [ 1 ] , args [ 2 ] , false , errorPos ) ;
1149
1149
}
1150
1150
1151
1151
// np(...) function
@@ -1166,9 +1166,9 @@ Expression ParseFunctionNullPropagation()
1166
1166
bool hasDefaultParameter = args . Length == 2 ;
1167
1167
Expression expressionIfFalse = hasDefaultParameter ? args [ 1 ] : Expression . Constant ( null ) ;
1168
1168
1169
- if ( _expressionHelper . TryGenerateAndAlsoNotNullExpression ( args [ 0 ] , hasDefaultParameter , out Expression generatedExpression ) )
1169
+ if ( _expressionHelper . TryGenerateAndAlsoNotNullExpression ( args [ 0 ] , true , out Expression generatedExpression ) )
1170
1170
{
1171
- return GenerateConditional ( generatedExpression , args [ 0 ] , expressionIfFalse , errorPos ) ;
1171
+ return GenerateConditional ( generatedExpression , args [ 0 ] , expressionIfFalse , true , errorPos ) ;
1172
1172
}
1173
1173
1174
1174
return args [ 0 ] ;
@@ -1234,7 +1234,7 @@ Expression ParseFunctionCast()
1234
1234
return Expression . ConvertChecked ( _it , resolvedType ) ;
1235
1235
}
1236
1236
1237
- Expression GenerateConditional ( Expression test , Expression expressionIfTrue , Expression expressionIfFalse , int errorPos )
1237
+ Expression GenerateConditional ( Expression test , Expression expressionIfTrue , Expression expressionIfFalse , bool nullPropagating , int errorPos )
1238
1238
{
1239
1239
if ( test . Type != typeof ( bool ) )
1240
1240
{
@@ -1244,30 +1244,71 @@ Expression GenerateConditional(Expression test, Expression expressionIfTrue, Exp
1244
1244
if ( expressionIfTrue . Type != expressionIfFalse . Type )
1245
1245
{
1246
1246
// If expressionIfTrue is a null constant and expressionIfFalse is ValueType:
1247
- // - create nullable constant from expressionIfTrue with type from expressionIfFalse
1248
- // - convert expressionIfFalse to nullable (unless it's already nullable)
1249
1247
if ( Constants . IsNull ( expressionIfTrue ) && expressionIfFalse . Type . GetTypeInfo ( ) . IsValueType )
1250
1248
{
1251
- Type nullableType = TypeHelper . ToNullableType ( expressionIfFalse . Type ) ;
1252
- expressionIfTrue = Expression . Constant ( null , nullableType ) ;
1253
- if ( ! TypeHelper . IsNullableType ( expressionIfFalse . Type ) )
1249
+ if ( nullPropagating && _parsingConfig . NullPropagatingUseDefaultValueForNonNullableValueTypes )
1254
1250
{
1255
- expressionIfFalse = Expression . Convert ( expressionIfFalse , nullableType ) ;
1251
+ // If expressionIfFalse is a non-nullable type:
1252
+ // generate default expression from the expressionIfFalse-type for expressionIfTrue
1253
+ // Else
1254
+ // create nullable constant from expressionIfTrue with type from expressionIfFalse
1255
+
1256
+ if ( ! TypeHelper . IsNullableType ( expressionIfFalse . Type ) )
1257
+ {
1258
+ expressionIfTrue = _expressionHelper . GenerateDefaultExpression ( expressionIfFalse . Type ) ;
1259
+ }
1260
+ else
1261
+ {
1262
+ expressionIfTrue = Expression . Constant ( null , expressionIfFalse . Type ) ;
1263
+ }
1264
+ }
1265
+ else
1266
+ {
1267
+ // - create nullable constant from expressionIfTrue with type from expressionIfFalse
1268
+ // - convert expressionIfFalse to nullable (unless it's already nullable)
1269
+
1270
+ Type nullableType = TypeHelper . ToNullableType ( expressionIfFalse . Type ) ;
1271
+ expressionIfTrue = Expression . Constant ( null , nullableType ) ;
1272
+
1273
+ if ( ! TypeHelper . IsNullableType ( expressionIfFalse . Type ) )
1274
+ {
1275
+ expressionIfFalse = Expression . Convert ( expressionIfFalse , nullableType ) ;
1276
+ }
1256
1277
}
1257
1278
1258
1279
return Expression . Condition ( test , expressionIfTrue , expressionIfFalse ) ;
1259
1280
}
1260
1281
1261
1282
// If expressionIfFalse is a null constant and expressionIfTrue is a ValueType:
1262
- // - create nullable constant from expressionIfFalse with type from expressionIfTrue
1263
- // - convert expressionIfTrue to nullable (unless it's already nullable)
1264
1283
if ( Constants . IsNull ( expressionIfFalse ) && expressionIfTrue . Type . GetTypeInfo ( ) . IsValueType )
1265
1284
{
1266
- Type nullableType = TypeHelper . ToNullableType ( expressionIfTrue . Type ) ;
1267
- expressionIfFalse = Expression . Constant ( null , nullableType ) ;
1268
- if ( ! TypeHelper . IsNullableType ( expressionIfTrue . Type ) )
1285
+ if ( nullPropagating && _parsingConfig . NullPropagatingUseDefaultValueForNonNullableValueTypes )
1269
1286
{
1270
- expressionIfTrue = Expression . Convert ( expressionIfTrue , nullableType ) ;
1287
+ // If expressionIfTrue is a non-nullable type:
1288
+ // generate default expression from the expressionIfFalse-type for expressionIfFalse
1289
+ // Else
1290
+ // create nullable constant from expressionIfFalse with type from expressionIfTrue
1291
+
1292
+ if ( ! TypeHelper . IsNullableType ( expressionIfTrue . Type ) )
1293
+ {
1294
+ expressionIfFalse = _expressionHelper . GenerateDefaultExpression ( expressionIfTrue . Type ) ;
1295
+ }
1296
+ else
1297
+ {
1298
+ expressionIfFalse = Expression . Constant ( null , expressionIfTrue . Type ) ;
1299
+ }
1300
+ }
1301
+ else
1302
+ {
1303
+ // - create nullable constant from expressionIfFalse with type from expressionIfTrue
1304
+ // - convert expressionIfTrue to nullable (unless it's already nullable)
1305
+
1306
+ Type nullableType = TypeHelper . ToNullableType ( expressionIfTrue . Type ) ;
1307
+ expressionIfFalse = Expression . Constant ( null , nullableType ) ;
1308
+ if ( ! TypeHelper . IsNullableType ( expressionIfTrue . Type ) )
1309
+ {
1310
+ expressionIfTrue = Expression . Convert ( expressionIfTrue , nullableType ) ;
1311
+ }
1271
1312
}
1272
1313
1273
1314
return Expression . Condition ( test , expressionIfTrue , expressionIfFalse ) ;
0 commit comments