简体   繁体   English

使用多态和Protobuf-net进行序列化和反序列化

[英]Serializing and Deserializing with Polymorphism and Protobuf-net

I'm trying to use protobuf-net to serialize objects. 我正在尝试使用protobuf-net来序列化对象。 I'm not sure if what I'm trying to do with inheritance is supported, but I thought I'd check and see if it is or if I'm just doing something wrong. 我不确定是否支持我正在尝试继承的内容,但我想我会检查并查看它是否存在或者我是否只是做错了什么。

Essentially, I'm trying to serialize some child class and then deserialize it back, but doing it with just a base class reference. 本质上,我正在尝试序列化一些子类,然后反序列化它,但只使用基类引用。 To demonstrate: 展示:

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();
    }
}

This outputs: 这输出:

Parent: 0

What I'd like it to output is: 我希望它输出的是:

Child: 3.14 42

Is this even possible? 这甚至可能吗? And if so, what am I doing wrong? 如果是这样,我做错了什么? I've read various questions on SO about inheritance and protobuf-net, and they're all a bit different than this example (as far as I've understood them). 我已经阅读了有关继承和protobuf-net的各种问题,它们与这个例子有点不同(据我所知)。

You'll kick yourself. 你会踢自己。 The code is fine except for one thing - you forgot to rewind the stream: 代码很好,除了一件事 - 你忘了回流:

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

As it was, the Deserialize was reading 0 bytes (because it was at the end), thus trying to create the parent type. 实际上, Deserialize是读取0个字节(因为它在最后),因此尝试创建父类型。 An empty stream is perfectly valid in terms of the protobuf specification - it just means an object without any interesting values. 就protobuf规范而言,空流完全有效 - 它只是一个没有任何有趣值的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM