2009-09-01 16 views
2

Protobuf/Protobuf-netと2つのクラスを使用して、1つの基底クラスと別の基底クラスから派生したクラス。
リストをシリアル化/逆シリアル化する方法はありますか?例えばProtobuf/Protobuf-netでオブジェクトの継承のリスト/配列を使用するには?

public class SomeBase 
{ 
    ... 
} 

public class SomeDerived : SomeBase 
{ 
    ... 
} 

、次のフィールドが直列化される:

public List<SomeBase> SomeList; 

がリストSomeBaseとSomeDerivedオブジェクトが含まれていることに注意してください。

答えて

3

これを機能させるには、サブタイプを識別するために使用するタグ(番号)を割り当てるだけです。基本的に、コアの "protocol buffers" wire specは継承を扱わないので、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++でこれを処理できるのでしょうか? 2番目の質問:これは.protoで行うことができますか?(どちらもyesの場合は.protoサンプルを与えることができますか? –

+0

@David protobuf-netはカプセル化を使って継承を実装しているので、SomeBeraseはSomeDerived型の任意フィールドを持ちます。 GetProto/GetSchemaではこれを説明していますが、.protoがそのような記述をするためのメタファーを持たないため、protobuf-netはcodegen層で継承を生成しません(.protoから開始する場合)。 –

関連する問題