【问题标题】:Make a generic deserializer with protocol buffer使用协议缓冲区制作通用反序列化器
【发布时间】:2018-06-13 17:09:54
【问题描述】:

我在 C# 和 C++ 上使用 RabbitMQ 和协议缓冲区。我有 5 个不同的类,每个类将包含一个字段“ActionType”。根据我想调用正确函数的操作类型的数量,但是当我从 RabbitMQ 获取消息时,当我想反序列化消息时,我不知道消息属于哪个类。有没有办法将消息反序列化/转换为通用对象,或者我只能从操作类型中获取值,然后反序列化消息?

【问题讨论】:

  • 你能有一个只有 ActionType 字段的基类吗?当你知道它的实际值时,首先反序列化到那个,然后用适当的类重复。
  • @PepitoSh 谢谢,我明白了!

标签: c# c++ protocol-buffers


【解决方案1】:

在 protobuf 术语中,这听起来像 oneof 场景,有 5 个子消息。 oneof 会给你一个鉴别器枚举和 5 条消息。含义:

message OuterMesage {
    oneof actionType {
        Foo foo = 1;
        Bar bar = 2;
        ...
    }
}
message Foo {...}
message Bar {...}
...

您将数据反序列化为OuterMesage,并通过.actionTypeCase(通常在switch)检查.foo/.bar等中的哪一个。


请注意,如果您使用的是 protobuf-net,也可以将完全相同的场景建模为继承,从而允许使用多态性;即

[ProtoContract]
[ProtoInclude(1, typeof(Foo)]
[ProtoInclude(2, typeof(Bar)]
public class OuterMessage { ... }

[ProtoContract]
public class Foo : OuterMessage {}

[ProtoContract]
public class Bar : OuterMessage {}

这实际上是 完全相同的数据布局,除了现在您从反序列化 OuterMessage 得到的消息将是 FooBar 等 - 视情况而定。因此,如果您在OuterMessage 上有一个virtual(或abstract)方法,则可以使用多态性来调用相应的方法:

var obj = Serializer.Deserialize<OuterMessage>(data); // obj could be Foo/Bar/etc
obj.DoTheThing(); // your virtual method

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多