2009-09-01 5 views
2

Protobuf/Protobuf-net과 두 클래스를 사용하여 하나의 기본 클래스와 다른 하나는 기본에서 파생됩니다.
목록을 serialize/deserialize하는 방법은 무엇입니까? 예를 들어Protobuf/Protobuf-net을 사용하여 일부 개체 상속의 목록/배열을 사용하는 방법?

:

public class SomeBase 
{ 
    ... 
} 

public class SomeDerived : SomeBase 
{ 
    ... 
} 

그리고 다음 필드는 직렬화 :

public List<SomeBase> SomeList; 

목록이 SomeBase 및 SomeDerived 개체가 포함되어 있음을 유의하십시오.

답변

3

이 기능을 사용하려면 하위 유형을 식별하는 데 사용할 태그 (번호)를 지정하기 만하면됩니다. 기본적으로 핵심 "프로토콜 버퍼"와이어 사양은 상속을 처리하지 않으므로 protobuf-net은 상속을 캡슐화로 모델링하여이를 달성합니다. 속성/필드의 태그는 [ProtoMember]이고 [ProtoInclude] ([XmlInclude]과 비교)을 통한 하위 유형을 할당합니다. 태그가 어떤 단일 유형 내에서 고유해야하지만이 하위 유형에 다시 사용할 수 있다는

주 -과 같이 태그 1.

를 사용하여 두 단계로 예제와 같이 :

using System.Collections.Generic; 
using ProtoBuf; 

[ProtoContract] 
[ProtoInclude(20, typeof(SomeDerived))] 
public class SomeBase 
{ 
    [ProtoMember(1)] 
    public string BaseProp { get; set; } 
} 
[ProtoContract] 
public class SomeDerived : SomeBase 
{ 
    [ProtoMember(1)] 
    public int DerivedProp { get; set; } 
} 
[ProtoContract] 
public class SomeEntity 
{ 
    [ProtoMember(1)] 
    public List<SomeBase> SomeList; 
} 

class Program 
{ 
    static void Main() 
    { 
     SomeEntity orig = new SomeEntity 
     { 
      SomeList = new List<SomeBase> { 
       new SomeBase { BaseProp = "abc"}, 
       new SomeDerived { BaseProp = "def", DerivedProp = 123} 
      } 
     }; 
     var clone = Serializer.DeepClone(orig); 
     // clone now has a list with 2 items, one each SomeBase and SomeDerived 
    } 
} 
+0

언제나처럼 훌륭한 답변! –

+0

2 가지 질문 : 다른 사람이 Java/C++에서이 문제를 처리 할 수 ​​있습니까? 두 번째 질문 :이 프로토 타입을 사용할 수 있습니까? (둘 다 가능하다면 .proto 샘플을 제공 할 수 있습니까? –

+0

) @David protobuf-net은 캡슐화를 통해 상속을 구현하므로 SomeBase는 SomeDerived 유형의 선택적 필드를 가지며 필드 번호 20 GetProto/GetSchema는이를 설명 할 것이지만, .proto가 그것을 기술 할 메타퍼가 없기 때문에 protobuf-net은 codegen 레이어에서 상속을 생성하지 않습니다 (.proto에서 시작하는 경우). –

관련 문제