Cysharp / MemoryPack

Zero encoding extreme performance binary serializer for C# and Unity.
MIT License
3.22k stars 189 forks source link

C# Multiple inheritance types lost on Serialization/Deserialization #318

Open tyl3rdurden opened 1 month ago

tyl3rdurden commented 1 month ago

Hello, I'm using the package really well after switching from JSON but I'm running into the following issue with multiple inheritance.

Data Layout

    [MemoryPackable]
    [MemoryPackUnion(1, typeof(Dog))]
    [MemoryPackUnion(2, typeof(Corgi))]
    public abstract partial class Animal {}

    [MemoryPackable] [Serializable]
    public partial class Dog : Animal { }

    [MemoryPackable] [Serializable]
    public partial class Corgi : Dog { }

    [MemoryPackable]
    public partial class DogWalker
    {
        public Dog Data;
    }

Failed Test

void Test() {   
    var dogWalker = new DogWalker();
    dogWalker.Data = new Corgi();

    var binarySerialized = MemoryPackSerializer.Serialize(dogWalker);
    var deserializedData = MemoryPackSerializer.Deserialize<DogWalker>(binarySerialized);

    Assert.True(deserializedData.Data is Corgi); // Always fails as original Corgi type is lost
}

The above test fails as the deserializedData.Data always becomes a Dog and not the original Corgi. Is there anyway to preserve the inheritance without having Dog also be an abstract class or changing DogWalker's Data type to be an Animal? I would like to prevent Cats from being put into the DogWalker.

Much thanks!

neuecc commented 1 week ago

It will be serialized using the declared type, not the actual type. Since it is declared as a Dog, it will be serialized as a Dog. If you want it to be a Dog or a Corgi, please declare it as an Animal.

tyl3rdurden commented 1 week ago

It will be serialized using the declared type, not the actual type. Since it is declared as a Dog, it will be serialized as a Dog. If you want it to be a Dog or a Corgi, please declare it as an Animal.

Thanks for the reply. However, I intended it to be declared as a Dog as I want to prevent Cats from being put into the DogWalker.