Skip to content

Commit 3ebae1a

Browse files
EgorBoeiriktsarpalis
authored andcommitted
[release/6.0] backport dotnet#62989 "Handle parameterless ctors in structs in STJ's ReflectionEmitMemberAccessor"
1 parent cc3b551 commit 3ebae1a

2 files changed

Lines changed: 68 additions & 0 deletions

File tree

src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ internal sealed class ReflectionEmitMemberAccessor : MemberAccessor
4949
else
5050
{
5151
generator.Emit(OpCodes.Newobj, realMethod);
52+
if (type.IsValueType)
53+
{
54+
// Since C# 10 it's now possible to have parameterless constructors in structs
55+
generator.Emit(OpCodes.Box, type);
56+
}
5257
}
5358

5459
generator.Emit(OpCodes.Ret);

src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.ParameterMatching.cs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,69 @@ public class ClassWithIgnoredSameType
13241324
public ClassWithIgnoredSameType(ClassWithIgnoredSameType prop) { }
13251325
}
13261326

1327+
[Fact]
1328+
public void StructWithPropertyInit_DeseralizeEmptyObject()
1329+
{
1330+
string json = @"{}";
1331+
var obj = JsonSerializer.Deserialize<StructWithPropertyInit>(json);
1332+
Assert.Equal(42, obj.A);
1333+
Assert.Equal(0, obj.B);
1334+
}
1335+
1336+
[Fact]
1337+
public void StructWithPropertyInit_OverrideInitedProperty()
1338+
{
1339+
string json = @"{""A"":43}";
1340+
var obj = JsonSerializer.Deserialize<StructWithPropertyInit>(json);
1341+
Assert.Equal(43, obj.A);
1342+
Assert.Equal(0, obj.B);
1343+
1344+
json = @"{""A"":0,""B"":44}";
1345+
obj = JsonSerializer.Deserialize<StructWithPropertyInit>(json);
1346+
Assert.Equal(0, obj.A);
1347+
Assert.Equal(44, obj.B);
1348+
1349+
json = @"{""B"":45}";
1350+
obj = JsonSerializer.Deserialize<StructWithPropertyInit>(json);
1351+
Assert.Equal(42, obj.A); // JSON doesn't set A property so it's expected to be 42
1352+
Assert.Equal(45, obj.B);
1353+
}
1354+
1355+
public struct StructWithPropertyInit
1356+
{
1357+
public long A { get; set; } = 42;
1358+
public long B { get; set; }
1359+
}
1360+
1361+
[Fact]
1362+
public void StructWithFieldInit_DeseralizeEmptyObject()
1363+
{
1364+
string json = @"{}";
1365+
var obj = JsonSerializer.Deserialize<StructWithFieldInit>(json);
1366+
Assert.Equal(0, obj.A);
1367+
Assert.Equal(42, obj.B);
1368+
}
1369+
1370+
public struct StructWithFieldInit
1371+
{
1372+
public long A;
1373+
public long B = 42;
1374+
}
1375+
1376+
[Fact]
1377+
public void StructWithExplicitParameterlessCtor_DeseralizeEmptyObject()
1378+
{
1379+
string json = @"{}";
1380+
var obj = JsonSerializer.Deserialize<StructWithExplicitParameterlessCtor>(json);
1381+
Assert.Equal(42, obj.A);
1382+
}
1383+
1384+
public struct StructWithExplicitParameterlessCtor
1385+
{
1386+
public long A;
1387+
public StructWithExplicitParameterlessCtor() => A = 42;
1388+
}
1389+
13271390
public async Task TestClassWithDefaultCtorParams()
13281391
{
13291392
ClassWithDefaultCtorParams obj = new ClassWithDefaultCtorParams(

0 commit comments

Comments
 (0)