4

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に関するさまざまな質問を読みましたが、それらはすべてこの例とは少し異なります(私が理解している限り)。

4

1 に答える 1

10

あなたは自分を蹴ります。コードは1つを除いて問題ありません-ストリームを巻き戻すのを忘れました:

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

それがそうであったように、Deserializeは0バイトを読み取っていたので(最後にあったため)、親タイプを作成しようとしました。空のストリームは、protobuf仕様の観点からは完全に有効です。これは、興味深い値のないオブジェクトを意味します。

于 2013-02-19T05:19:08.730 に答える