【问题标题】:Serializing and Deserializing with Polymorphism and Protobuf-net使用多态性和 Protobuf-net 进行序列化和反序列化
【发布时间】:2013-02-03 15:42:39
【问题描述】:

我正在尝试使用protobuf-net 来序列化对象。我不确定是否支持我尝试对继承进行的操作,但我想我会检查一下是否支持,或者我是否只是做错了什么。

本质上,我正在尝试序列化一些子类,然后将其反序列化,但只使用基类引用。演示:

using UnityEngine;
using System.Collections;
using ProtoBuf;

public class main : MonoBehaviour
{
    // If I don't put "SkipConstructor = true" I get
    // ProtoException: No parameterless constructor found for Parent
    // Ideally, I wouldn't have to put "SkipConstructor = true" but I can if necessary
    [ProtoContract(SkipConstructor = true)]
    [ProtoInclude(1, typeof(Child))]
    abstract class Parent
    {
        [ProtoMember(2)]
        public float FloatValue
        {
            get;
            set;
        }

        public virtual void Print()
        {
            UnityEngine.Debug.Log("Parent: " + FloatValue);
        }
    }

    [ProtoContract]
    class Child : Parent
    {
        public Child()
        {
            FloatValue = 2.5f;
            IntValue   = 13;
        }

        [ProtoMember(3)]
        public int IntValue
        {
            get;
            set;
        }

        public override void Print()
        {
            UnityEngine.Debug.Log("Child: " + FloatValue + ", " + IntValue);
        }
    }

    void Start()
    {
        Child child = new Child();
        child.FloatValue = 3.14f;
        child.IntValue   = 42;

        System.IO.MemoryStream ms = new System.IO.MemoryStream();

        // I don't *have* to do this, I can, if needed, just use child directly.
        // But it would be cool if I could do it from an abstract reference
        Parent abstractReference = child; 

        ProtoBuf.Serializer.Serialize(ms, abstractReference);

        ProtoBuf.Serializer.Deserialize<Parent>(ms).Print();
    }
}

这个输出:

Parent: 0

我希望它输出的是:

Child: 3.14 42

这甚至可能吗?如果是这样,我做错了什么?我已经阅读了关于继承和 protobuf-net 的各种关于 SO 的问题,它们都与这个示例有些不同(据我所知)。

【问题讨论】:

    标签: c# unity3d protocol-buffers protobuf-net


    【解决方案1】:

    你会踢自己的。代码很好,除了一件事 - 你忘了倒带:

    ProtoBuf.Serializer.Serialize(ms, abstractReference);
    ms.Position = 0; // <========= add this
    ProtoBuf.Serializer.Deserialize<Parent>(ms).Print();
    

    事实上,Deserialize 正在读取 0 个字节(因为它在末尾),因此试图创建父类型。就 protobuf 规范而言,空流是完全有效的——它只是意味着一个没有任何有趣值的对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多