Unity 自带的Json工具JsonUtility关于多态对象序列化问题

问题描述:

我有一个抽象类A有a和b属性,
对象B继承自对象A,且对象B中有其特有的属性c和d
对象C继承自对象A,且对象C中有其特有的属性e和f
对象D是一个集合对象存储所有A的派生对象
当我序列化对象D的时候会发现生成的json中只有a和b属性,派生对象的特有属性无法序列化

[Serializable]
public abstract class A{
    public string a;
    public int b;
}

[Serializable]
public class B:A{
    public float c;
    public bool d;
}

[Serializable]
public class C:A{
    public float e;
    public string f;
}

[Serializable]
public class D{
public List<A> list = new List<A>();
}

解决问题

改造集合对象D,使对象D继承接口(ISerializationCallbackReceiver),然后在序列化之前将List包装成List<Serializable_A>,
Serializable_A是对象的具体形态,包含这个对象的所有属性,然后再在反序列化之后将List<Serializable_A>转化为List。这样就解决了上述问题。

[Serializable]
public class D: ISerializationCallbackReceiver{
    [NonSerialized]
    public List<A> list = new List<A>();
    [SerializeField]
    private List<Serializable_A> serializableList= new List<Serializable_A>();

    public void OnBeforeSerialize()
    {
        if (list == null || list.Count <= 0)
        {
            serializableList.Clear();
            return;
        }

        for (int i = 0; i < cardList.Count; i++)
        {
            Serializable_A obj = new Serializable_A(list[i]);
            serializableList.Add(obj);
        }
    }

    public void OnAfterDeserialize()
    {
        if (list == null) list = new List<A>();
        else list.Clear();
        if (serializableList == null || serializableList.Count <= 0) return;
        for (int i = 0; i < serializableList.Count; i++)
        {
            Serializable_A serA = serializableList[i];
            list.Add(serA.GetA());
        }
        serializableList.Clear();
    }


    [Serializable]
    private class Serializable_A{
        private string csName;
        public B b;
        public C c;

        public Serializable_A(A a){
            csName=a.GetType().Name;
            switch (csName)
            {
                case nameof(B):
                    b=a as B;
                    break;
                case nameof(C):
	                c=a as C;
	                break;
            }
        }

        public A GetA()
        {
            switch (csName)
            {
                case nameof(B):
                    return b;
                case nameof(C):
                    return c;
                break;
            }
            return null;
        }

    }

}

美中不足

解决问题之后发现Serializable_A对象中的a或b属性就算为空引用,也会在序列化时自动构造对象来填补这个空引用,当然这并不会影响什么,但是仍然期待有更好的解决方案,有好方案的小伙伴可以底部留言哦

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

司军礼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值