2011-06-17 48 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 
{ 

} 

即基本需要了解的後裔。不是,我將序列化中的鑑別符刪除,因爲如果它與對象類型直接相關 - 它通過ProtoInclude在內部處理它,並且將爲您創建正確的類型,因此它是多餘的。每種類型的需要知道關於直接亞型,即

A 
- B 
- C 
- D 
- E 
- F 

這裏A需要知道B和d; B需要知道C; D需要知道E和F.

請注意,「這是什麼」枚舉在這裏是一個好主意,但不需要它是一個字段 - 沒有字段的虛擬屬性可能更合適。如果我誤解了,並且消息類型不是與對象類型有關,那麼請忽略我; p

另外:public fields - 不這樣做。想想小貓......它會工作,但性能是首選(一般來說,我的意思是;與protobuf網無關)。

+0

+1爲公共字段 - 不要這樣做。想想小貓。*真的。 –

+0

我不明白爲什麼,但它看起來並不像你描述的那樣。我試圖發送更簡單的消息。當我做'Akcja temp =(Akcja)ann;'我得到_Unhandled異常:System.InvalidCastException:不能從源類型轉換到目標type_。當我嘗試接收Akcja時,我可以得到相同的結果。 –

+0

@主 - 你*序列*它作爲'Akcja'? (是否與'Update'相同?)。很高興幫助,但需要確保我正在回答正確的事情... –