JasonXuDeveloper / Nino

Definite useful and high performance serialization library for any C# projects, including but not limited to .NET Core apps or Unity/Godot games.
https://nino.xgamedev.net
MIT License
468 stars 44 forks source link

多态相关,抽象类直接作为成员变量时序列化报错 #58

Closed 526077247 closed 1 year ago

526077247 commented 1 year ago

多态相关,抽象类直接作为成员变量时序列化报错

using Nino.Serialization;
using UnityEngine;

namespace Nino.Test.Editor.Serialization
{
    public abstract class AbstractClass
    {
        [NinoMember(1)]
        public int B;
    }

    [NinoSerialize]
    public class ClassA: AbstractClass
    {
        [NinoMember(2)]
        public int A;
    }

    [NinoSerialize]
    public class ClassB
    {
        [NinoMember(1)]
        public AbstractClass Class;
    }
    public static class Test12
    {
        private const string SerializationTest12 = "Nino/Test/Serialization/Test12 - Serialize (Abstract)";

        [UnityEditor.MenuItem(SerializationTest12,priority=12)]
        public static void Main()
        {
            ClassB b = new ClassB();
            b.Class = new ClassA()
            {
                A = 1,
                B = 2,
            };

            var bytes = Serializer.Serialize(b);
            ClassB bb = Deserializer.Deserialize<ClassB>(bytes);
            Debug.Log(bb.Class.GetType());
        }
    }
}

InvalidOperationException: The type Nino.Test.Editor.Serialization.AbstractClass does not have NinoSerialize attribute or custom importer/exporter Nino.Serialization.TypeModel.TryGetModel (System.Type type, Nino.Serialization.TypeModel& model) (at Assets/Nino/Serialization/TypeModel.cs:207) Nino.Serialization.Serializer.Serialize[T] (System.Type type, T value, Nino.Serialization.Writer writer, Nino.Serialization.CompressOption option, System.Boolean returnValue) (at Assets/Nino/Serialization/Serializer.cs:171) Nino.Serialization.Serializer.Serialize[T] (System.Type type, T value, Nino.Serialization.Writer writer, Nino.Serialization.CompressOption option, System.Boolean returnValue) (at Assets/Nino/Serialization/Serializer.cs:218) Nino.Serialization.Serializer.Serialize[T] (T val, Nino.Serialization.CompressOption option) (at Assets/Nino/Serialization/Serializer.cs:51) Nino.Test.Editor.Serialization.Test12.Main () (at Assets/Nino/Test/Editor/Serialization/Test12.cs:39)

JasonXuDeveloper commented 1 year ago

The type Nino.Test.Editor.Serialization.AbstractClass does not have NinoSerialize attribute or custom importer/exporter

给这个类打个标签[NinoSerialize]

526077247 commented 1 year ago

还有个问题,用了抽象类,生成出来的代码就有问题了

JasonXuDeveloper commented 1 year ago

ok,你先试试打个标签后能用不

526077247 commented 1 year ago

打了标签后,报其他的错了。 MissingMethodException: Default constructor not found for type Nino.Test.Editor.Serialization.AbstractClass System.RuntimeType.CreateInstanceMono (System.Boolean nonPublic, System.Boolean wrapExceptions) (at <9aad1b3a47484d63ba2b3985692d80e9>:0) System.RuntimeType.CreateInstanceSlow (System.Boolean publicOnly, System.Boolean wrapExceptions, System.Boolean skipCheckThis, System.Boolean fillCache) (at <9aad1b3a47484d63ba2b3985692d80e9>:0) System.RuntimeType.CreateInstanceDefaultCtor (System.Boolean publicOnly, System.Boolean skipCheckThis, System.Boolean fillCache, System.Boolean wrapExceptions, System.Threading.StackCrawlMark& stackMark) (at <9aad1b3a47484d63ba2b3985692d80e9>:0) System.Activator.CreateInstance (System.Type type, System.Boolean nonPublic, System.Boolean wrapExceptions) (at <9aad1b3a47484d63ba2b3985692d80e9>:0) System.Activator.CreateInstance (System.Type type, System.Boolean nonPublic) (at <9aad1b3a47484d63ba2b3985692d80e9>:0) System.Activator.CreateInstance (System.Type type) (at <9aad1b3a47484d63ba2b3985692d80e9>:0) Nino.Serialization.Deserializer.Deserialize (System.Type type, System.Object val, System.Span1[T] data, Nino.Serialization.Reader reader, Nino.Serialization.CompressOption option, System.Boolean returnDispose) (at Assets/Nino/Serialization/Deserializer.cs:205) Nino.Serialization.Deserializer.Deserialize (System.Type type, System.Object val, System.Span1[T] data, Nino.Serialization.Reader reader, Nino.Serialization.CompressOption option, System.Boolean returnDispose) (at Assets/Nino/Serialization/Deserializer.cs:268) Nino.Serialization.Deserializer.Deserialize[T] (System.Span`1[T] data, Nino.Serialization.Reader reader, Nino.Serialization.CompressOption option, System.Boolean returnDispose) (at Assets/Nino/Serialization/Deserializer.cs:120) Nino.Serialization.Deserializer.Deserialize[T] (System.Byte[] data, Nino.Serialization.CompressOption option) (at Assets/Nino/Serialization/Deserializer.cs:48) Nino.Test.Editor.Serialization.Test12.Main () (at Assets/Nino/Test/Editor/Serialization/Test12.cs:41)

JasonXuDeveloper commented 1 year ago

ok,我这几天去解决一下,目前可以根据UnitTest里的polymorphismTest写个多态代码

JasonXuDeveloper commented 1 year ago

https://github.com/JasonXuDeveloper/Nino/blob/fd7d5afc0235757bdb457d782a73b101f1693d41/src/Nino.UnitTests/ComplexSerializationTest.cs#L434

526077247 commented 1 year ago

    [NinoSerialize]
    public abstract class AbstractClass
    {
        [NinoMember(1)]
        public int B;
    }

    [NinoSerialize]
    public class ChildClass: AbstractClass
    {
        [NinoMember(2)]
        public int A;
    }

    [NinoSerialize]
    public class TestAbstract
    {
        [NinoMember(1)]
        public Base Base;
        [NinoMember(2)]
        public AbstractClass AbstractClass;
    }
    public partial class ComplexSerializationTest
    {
        [TestMethod]
        public void TestAbstractClass()
        {
            TestAbstract test = new TestAbstract();
            test.Base = new Derived()
            {
                A = 999,
                B = 456
            };
            test.AbstractClass = new ChildClass()
            {
                A = 111,
                B = 99
            };
            var buf = Serializer.Serialize(test);
            var data2 = Deserializer.Deserialize<TestAbstract>(buf);
            Assert.AreEqual(data2.AbstractClass.GetType(), typeof(ChildClass));
            Assert.AreEqual(data2.Base.GetType(), typeof(Derived));
        }
    }
JasonXuDeveloper commented 1 year ago

不打算支持抽象类了,因为会大幅度扩大Collection类型的体积