转换为后代类型
我使用 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技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它应该正常工作;我相信问题在于属性被颠倒了(在这种情况下我会记下笔记以提出更清晰的错误) - 它应该是:
即基础需要了解后代。不是我从序列化中删除了鉴别器,因为这是多余的如果它直接与对象类型相关 - 它通过
ProtoInclude
在内部处理这个问题并且将为您创建正确的类型。每个类型只需要了解直接子类型,即这里 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 :
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.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).