转换为后代类型

发布于 2024-11-16 03:10:15 字数 1391 浏览 2 评论 0原文

我使用 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;

I receive a message using protobuf-net. The message has 1 field with the type of the message stored in it (the field is of enum type). Now I know the message is of a type that inherit from the base type. How can I cast the object I get from the Serializer to the appriopriate type?

Definition of 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;
    }

How can I do something in idea similiar to this:

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寄居人 2024-11-23 03:10:15

它应该正常工作;我相信问题在于属性被颠倒了(在这种情况下我会记下笔记以提出更清晰的错误) - 它应该是:

[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 无关)。

It should just work; I believe the problem is that the attributes are inverted (I will take a note to raise a clearer error in this case) - it should be :

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

}

[ProtoContract]
class Update : Announcement
{

}

i.e. the base needs to know about the descendants. Not I removed the discriminator from serialization, as that is redundant if it relates directly to the object type - it handles this internally via the ProtoInclude and will create the correct type for you. Each type needs to know only about the direct subtypes, i.e.

A
- B
 - C
- D
 - E
 - F

here A needs to know about B and D; B needs to know about C; D needs to know about E and F.

Note that a "what is this" enum is a good idea here, but there is no need for it to be a field - a virtual property without a field may be more appropriate. If I have misundersood and the message-type doesn't relate to the object-type, then ignore me ;p

Also: public fields - don't do it. Think of the kittens... It will work, but properties are preferred (in general, I mean; nothing to do with protobuf-net).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文