2013-02-19 3 views
3

protobuf-net을 사용하여 개체를 직렬화하려고합니다. 상속으로 무엇을하려고하는지 잘 모르겠다.하지만 내가 틀렸는지를 확인하고보고 있는지 생각했다.다형성 및 Protobuf-net을 사용하여 직렬화 및 역 직렬화

기본적으로 일부 자식 클래스를 serialize하고 다시 역 직렬화하려고하지만 기본 클래스 참조만으로 처리하려고합니다. 설명하기 :

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에 관한 여러 가지 질문을 읽었습니다. 그리고이 예제와는 조금 다릅니다 (이해할 수있는 한).

답변

8

자신을 걷어차 야합니다. 코드는 한 가지를 제외하고 괜찮 - 당신이 스트림 되감기하는 것을 잊었다 : (이 말 때문에) 따라서 부모 유형을 만들려고, 그것이로서

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

Deserialize 0 바이트를 읽어되었다. 빈 스트림은 protobuf 사양 측면에서 완벽하게 유효합니다. 단지 흥미로운 값이없는 객체를 의미합니다.

+1

오. 나의. 지옥. 진지하게, 나는 내가 가지고 있어야하는 것보다 이것에서 더 오래 waaay를 보냈다. 정말 고맙습니다! – Cornstalks

+3

@Cornstalks 나는 당신이 스스로를 차버릴 것이라고 말했지만, 진지하게 : 재현 할 수있는 예제를 게시 해 주셔서 감사합니다. –

+1

셀프 키커 체크인, 감사합니다! – thumbmunkeys