приведение к типу потомка - PullRequest
1 голос
/ 17 июня 2011

Я получаю сообщение, используя protobuf-net. Сообщение имеет 1 поле с типом сохраненного в нем сообщения (поле имеет тип enum). Теперь я знаю, что сообщение относится к типу, который наследуется от базового типа. Как я могу привести объект, который я получаю от Сериализатора, к типу «Призрачный»?

Определение классов:

[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 Ответ

1 голос
/ 17 июня 2011

должно просто работать ; Я считаю, что проблема заключается в том, что атрибуты инвертированы (я приму к сведению, чтобы поднять более ясную ошибку в этом случае) - это должно быть:

[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

Также: публичные поля - не делайте этого. Подумайте о котятах ... Это будет работать , но свойства предпочтительнее (в общем, я имею в виду; ничего общего с protobuf-net).

...