Init-only property in CircularReference class is not Deserialized
Expected Behavior
Deserialization behaviour of init-only properties should be independent of the GenerateType and deserialize correctly for CircularReference-annotated types.
Current Behavior
Init-only properties in CircularReference-annotated types are not deserialized
Workaround
Don't serialize Init-only properties and use a private backing field for (de-)serialization.
Steps to Reproduce
using MemoryPack;
namespace MemoryPackTest
{
internal class Program
{
static void Main(string[] args)
{
TestCircularInitOnlyPacking();
return;
}
static void TestCircularInitOnlyPacking()
{
MyCircularType instance = new() { Test = 2 };
byte[] bytes = MemoryPackSerializer.Serialize<MyCircularType>(instance);
MyCircularType? result = MemoryPackSerializer.Deserialize<MyCircularType>(bytes);
Console.WriteLine(instance.Test); // Output: 2
Console.WriteLine(result?.Test); // Output: -1
}
}
[MemoryPackable(GenerateType.CircularReference)]
internal partial class MyCircularType
{
[MemoryPackOrder(0)]
public int Test { get; init; } = -1;
}
}
Cause
It is caused by the Generated Deserializer calling the parameter-less constructor without any object initializers.
This only happens with CircularReference types, as they are constructed separately for the ref-handling system, before the properties are set:
Additionally, since such an object's value is never null after this, the generated NEW path is redundant and never taken:
The SET path can't do anything, because the property is init-only:
Comment
I am not sure if this is intended. If it is, it should be stated clearly in the ReadMe. If this is a bug, this might not be that easy to fix. A possible fix could be to first deserialize all init-only properties and then to construct the object. This would probably lead to issues if an init-only property type contains a circular reference to this object, but maybe that could be caught by a compiler check. In any case, thank you for this project. Other than this, it was quite easy to integrate into my codebase :D
Thanks for the detailed report, this looks like a problem that needs to be fixed. I'll give it a try.
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 30 days.