2011-06-17 14 views
1

protobuf-netを使用してメッセージを受け取ります。メッセージには、その中に格納されているメッセージのタイプ(フィールドは列挙型)の1つのフィールドがあります。今、私はメッセージが基底型から継承した型であることを知っています。私はシリアライザから取得したオブジェクトを適切な型にキャストするにはどうすればよいですか?子孫型へのキャスト

クラスの定義:どのように私はこれに似アイデアで何かを行うことができます

[ProtoContract] 
class Annoucement 
    { 
     public enum msgType 
     { 
      AKCJA = 0, 
      CZEKAJ = 1, 
      GOTOWY = 2, 
      NOWY_GRACZ = 3, 
      LISTA_GRACZY = 4, 
      ERROR = 5, 
      MAPA = 6, 
      UPDATE = 7, 
      LISTAGIER = 8, 
      JOINGAME = 9, 
      QUIT = 10 
     } 
     [ProtoMember(1)] 
     public msgType typ; 
    } 

[ProtoContract, ProtoInclude(14, typeof(Annoucement))] 
    class Update : Annoucement 
    { 
     [ProtoMember(1)] 
     public List<Tank> czolg; 
     [ProtoMember(2)] 
     public List<Pocisk> pocisk; 
     [ProtoMember(3, IsRequired = false)] 
     public List<Bonus> bonus; 
    } 

:それはだけを動作するはず

Annoucement ann = Serializer.DeserializeWithLengthPrefix<Annoucement> (str, PrefixStyle.Base128); 
switch (ann.typ) { 
case Annoucement.msgType.UPDATE: 

       { 
        Update temp = (Update)ann; 
        Console.WriteLine (temp.czolg.Count); 
        List<Tank>.Enumerator i = temp.czolg.GetEnumerator(); 
        Console.WriteLine (i.Current.life); 
       } 


       break; 

答えて

1

。私は(私はこのケースで明確なエラーを発生させるためにノートを取る)問題は属性が反転していることであると考えている - それは次のようになります。

[ProtoContract, ProtoInclude(14, typeof(Update))] 
class Annoucement 
{ 

} 

[ProtoContract] 
class Update : Announcement 
{ 

} 

すなわちベースは子孫について知っておく必要があります。 discriminatorを直列化から削除したわけではありません。つまり、オブジェクトタイプに直接関連する場合は冗長なです。これは内部でProtoIncludeで処理し、正しいタイプを作成します。各タイプは、直接サブタイプ約のみを知る必要がある、すなわち

A 
- B 
- C 
- D 
- E 
- F 

ここでAは、BとDについて知る必要があります。 BはCについて知る必要があります。 DはEとFについて知る必要があります。

ここでは「これは何ですか?」という列挙型は良いアイデアですが、フィールドである必要はありません。フィールドを持たない仮想プロパティが適切かもしれません。私が誤解を招き、メッセージタイプがオブジェクトタイプに関連しないの場合、私を無視してください;

また、パブリックフィールド - それはしないでください。子猫を考える... ですが、プロパティが優先されます(一般的には、protobuf-netとは関係ありません)。

+0

*パブリックフィールドの場合は+1しないでください。子猫のことを考えてください。*本当です。 –

+0

私は理由を理解できませんが、問題を説明したようには見えません。私はもっ​​と簡単なメッセージを送ろうとしました。私が 'Akcja temp =(Akcja)ann;を実行すると、_Unhandled例外が発生します。System.InvalidCastException:ソースタイプから宛先タイプにキャストできません。代わりにAkcjaを受け取ろうとすると、同じことが起こります。 –

+0

@lord - それを 'Akcja'としてシリアライズしましたか? (これは 'Update'と同じですか?)助けて嬉しいですが、私が正しいことに答えていることを確かめる必要があります... –