多态性和Protobuf-net的串行化和反串行化
本文关键字:反串 Protobuf-net 多态性 | 更新日期: 2023-09-27 17:59:54
我正在尝试使用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
这可能吗?如果是这样,我做错了什么?我在SO上读过关于继承和protobuf-net的各种问题,它们都与这个例子有点不同(据我所知)。
你会踢自己的。代码很好,除了一件事——你忘记倒带了:
ProtoBuf.Serializer.Serialize(ms, abstractReference);
ms.Position = 0; // <========= add this
ProtoBuf.Serializer.Deserialize<Parent>(ms).Print();
实际上,Deserialize
正在读取0个字节(因为它在末尾),因此试图创建父类型。根据protobuf规范,空流是完全有效的——它只是指一个没有任何有趣值的对象。