【问题标题】:Serialize a Run-Time Message Contract with Protobuf-Net使用 Protobuf-Net 序列化运行时消息合约
【发布时间】:2014-08-07 09:41:42
【问题描述】:

假设我有一些数据

1: {
    1: 0.0
    2: 1
    3: "2"
    4: true
}

但在编译时我不知道合约。然而,在运行时,我可以加载一个数据描述符,它告诉我我有多少个字段以及每个字段中的每种类型是什么。即

new Type[]{
   typeof(double),
   typeof(int),
   typeof(string),
   typeof(bool)};

问:如何在运行时获取 protocol-buf 以从给定数据描述的流中读取(和写入)消息?

我目前的想法是:在给定数据描述的情况下,在运行时(发出)创建一个类型,然后使用它进行 protocol-buf 序列化/反序列化。然后通过反射/动态访问属性。不确定这是否是个好主意。

这是Serialize object[] with Protobuf-net的另一种方法

【问题讨论】:

    标签: c# protocol-buffers protobuf-net


    【解决方案1】:

    我想知道您是否最好只使用扩展成员 API;像

    [TestFixture]
    public class SO25179186
    {
        [Test]
        public void RuntimeMessageContract()
        {
            var adhoc = new AdHoc();
            Extensible.AppendValue<double>(adhoc, 1, 0.0);
            Extensible.AppendValue<int>(adhoc, 2, 1);
            Extensible.AppendValue<string>(adhoc, 3, "2");
            Extensible.AppendValue<bool>(adhoc, 4, true);
    
            var clone = Serializer.DeepClone(adhoc);
            Assert.AreNotSame(clone, adhoc);
            Assert.AreEqual(0.0, Extensible.GetValue<double>(clone, 1));
            Assert.AreEqual(1, Extensible.GetValue<int>(clone, 2));
            Assert.AreEqual("2", Extensible.GetValue<string>(clone, 3));
            Assert.AreEqual(true, Extensible.GetValue<bool>(clone, 4));
        }
    
        [ProtoContract]
        class AdHoc : Extensible {}
    }
    

    protobuf-net 中目前没有其他“即席对象定义”API。然而,上述的一些变体可以与 Type 一起使用,而不是泛型。

    请注意,您没有Extensible 继承;你也可以手动实现IExtensibleExtensible 只是方便。请注意,IExtensible 除了在类型上声明的任何 protobuf 字段之外起作用。

    【讨论】:

    • 差不多了,但我需要使用非泛型:Extensible.AppendValue(model, adhoc, 1, DataFormat.Default, Activator.CreateInstance(expectedType)); ... 这也可以。 :)
    • 如果我选择使用 Extensible,而不是 Emitting 动态类,我会受到性能损失吗?即解串器未编译等?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多