You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi! I really like MemoryPack (and pretty much everything else published under Cysharp, for that matter).
I initially ran into an issue with how all public members are included by default (described in #342), but that prompted a further dig into why a certain property was being included by default.
Expression bodied properties (ie. properties defined with =>) and readonly properties (ie. lacking a setter) are included by default if they are public. This is problematic because:
expression-bodied properties don't always represent/correspond to an actual value in memory, in my experience it's common for them to represent transient (ie. computed) values or straight up constants
imo this runs counter to expectations, or maybe just my mental model of how serialising runtime state should work
without a setter deserialisation cannot be accomplished without manual implementation via [MemoryPackConstructor]
Example:
[MemoryPackable]publicpartialclassMyClass{privateintmyInt;// these are all included without any warningspublicintMyIntWrapper=>myInt;publicintMyIntSqrd=>myInt*myInt;publicfloatPi=>3.14f;publicintMyReadonlyInt{get;}}
This produces the following sections in the generated MyClass.Deserialize:
These values are serialised and will be read from the reader, but cannot be written to the result.
From what I can see the intended workaround for this is to use a constructor to manually handle this (with [MemoryPackConstructor] if there are multiple constructors).
There should be a warning if there is an included property without a setter and no parameterised constructor. This seems like a bug, and probably warrants its own issue (#344might be referring to this problem but the example given isn't specific to properties lacking setters).
My intuition says that properties without setters shouldn't be serialised at all, particularly expression-bodied properties since they usually represent transient values. The lack of a setter is perfectly adequate justification for excluding them by default and requiring explicit inclusion from the user via [MemoryPackInclude], imo. This would make it clear to the user that this is a special case and a warning (described above) would quickly explain that further work is required for that to work.
The text was updated successfully, but these errors were encountered:
Grimeh
changed the title
Expression bodied properties shouldn't be included by default
Properties without a setter shouldn't be included by default
Jan 1, 2025
I have one thing to add:
This applies to ICollection properties too.
But in my case i assumed that if the collection is read-only (i.e. automatically generated by the class) the MemoryPack would just check it for null and use the Add method provided by the ICollection interface, but after looking at the generated code it appears to not be the case. It serializes the collection, deserializes it into a temporary field and then... just does nothing with it?
This seemed quite strange to me until i stumbled upon your issue and then it became very clear to me why it behaves like that.
Hi! I really like MemoryPack (and pretty much everything else published under Cysharp, for that matter).
I initially ran into an issue with how all public members are included by default (described in #342), but that prompted a further dig into why a certain property was being included by default.
Expression bodied properties (ie. properties defined with
=>
) and readonly properties (ie. lacking a setter) are included by default if they are public. This is problematic because:[MemoryPackConstructor]
Example:
This produces the following sections in the generated
MyClass.Deserialize
:These values are serialised and will be read from the reader, but cannot be written to the result.
From what I can see the intended workaround for this is to use a constructor to manually handle this (with
[MemoryPackConstructor]
if there are multiple constructors).There should be a warning if there is an included property without a setter and no parameterised constructor. This seems like a bug, and probably warrants its own issue (#344 might be referring to this problem but the example given isn't specific to properties lacking setters).
My intuition says that properties without setters shouldn't be serialised at all, particularly expression-bodied properties since they usually represent transient values. The lack of a setter is perfectly adequate justification for excluding them by default and requiring explicit inclusion from the user via
[MemoryPackInclude]
, imo. This would make it clear to the user that this is a special case and a warning (described above) would quickly explain that further work is required for that to work.The text was updated successfully, but these errors were encountered: