2011-06-17 8 views
1

Je reçois un message en utilisant protobuf-net. Le message a 1 champ avec le type du message stocké dedans (le champ est de type enum). Maintenant, je sais que le message est d'un type qui hérite du type de base. Comment est-ce que je peux jeter l'objet que je reçois du Serializer au type approprié?Transférer vers un type descendant

Définition des classes:

[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; 
    } 

Comment puis-je faire quelque chose idée similaire à ceci:

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; 

Répondre

1

Il devrait travailler juste; Je crois que le problème est que les attributs sont inversés (je prendrai une note pour élever une erreur plus claire dans ce cas) - il devrait être:

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

} 

[ProtoContract] 
class Update : Announcement 
{ 

} 

à savoir la base a besoin de savoir sur les descendants. Non, j'ai supprimé le discriminateur de la sérialisation, car il est redondant s'il concerne directement le type d'objet - il le gère en interne via le ProtoInclude et créera le type correct pour vous. Chaque type a besoin de savoir que sur les sous-types directs, à savoir

A 
- B 
- C 
- D 
- E 
- F 

ici un besoin de connaître B et D; B a besoin de savoir sur C; D doit connaître E et F.

Notez qu'une énumération "qu'est-ce que c'est?" Est une bonne idée ici, mais il n'est pas nécessaire que ce soit un champ - une propriété virtuelle sans champ peut être plus appropriée . Si je misundersood et le message de type ne pas concernent le type d'objet, puis me ignorer, p

également: champs publics - ne le font pas. Pensez aux chatons ... Il va travailler, mais les propriétés sont préférées (en général, je veux dire, rien à voir avec protobuf-net).

+0

+1 pour les champs publics - ne le faites pas. Pense aux chatons. * Tellement vrai. –

+0

Je ne comprends pas pourquoi mais il ne semble pas que vous ayez décrit le problème. J'ai essayé d'envoyer un message plus simple. Quand je fais 'Akcja temp = (Akcja) ann;' Je reçois _Unhandled Exception: System.InvalidCastException: Impossible de convertir le type de source en type de destination_. Quand j'essaie de recevoir Akcja à la place, je reçois la même chose. –

+0

@lord - l'avez-vous * sérialisé * en tant que 'Akcja'? (est-ce la même chose que 'Update'?). Heureux d'aider, mais je dois être sûr que je réponds à la bonne chose ... –

Questions connexes