protobuf-net文档或替代方案

时间:2013-09-15 19:16:42

标签: .net serialization protobuf-net

Protobuf-net似乎是最快的,并且对于高性能需要最推荐的.NET序列化库。我真的很想使用它,因为我需要通过线路发送数十万个对象。

然而,我无法入门。文档(github上的wiki)非常稀少,特别是对于v2。

不知何故,你们那里似乎能够开始使用lib。怎么样?通过阅读消息来源?试错了?或者是否有一些我不知道的API文档/教程? (我只知道GitHib页面。)

谢谢和欢呼,

P.S。:我需要使用RuntimeTypeModel(没有属性的POCO)。

3 个答案:

答案 0 :(得分:6)

既然你也问过替代品......

不需要属性修饰是创建Migrant快速序列化库和简单API的原因之一。图书馆有一些想法也存在于protobuf中(所以我们或多或少在速度和大小方面都相同),但同时试图解决不同的问题。在与protobuf不同的特征中,空集合和空集合之间存在差异,整个序列化是基于引用的参考和基于值的值(嗯,您也可以将引用视为一种特殊的值)。 github上的README应该能够回答你的大部分问题;是否需要更详细的信息,请问。

自定义对象序列化的简单场景:

var stream = new MyCustomStream();
var myComplexObject = new MyComplexType(complexParameters);
var serializer = new Serializer();

serializer.Serialize(myComplexObject, stream);

stream.Seek(0, SeekOrigin.Begin);

var myDeserializedObject = serializer.Deserialize<MyComplexType>(stream);

请注意,Deserialize中的预期类型仅用于具有反序列化对象的良好编译时类型,您也可以使用常规object

免责声明:我是开发人员之一。

答案 1 :(得分:1)

在protobuf中,每个类型的成员都需要一个识别号,因为protobuf是基于数字的(它不发送名称)。因此,诀窍很简单:告诉它使用什么数字。例如:

class Customer {
    public int Id {get;set;}
    public string Name {get;set;}
}

为此指定合同的最简单方法是:

RuntimeTypeModel.Default.Add(typeof(Customer), false).Add("Id", "Name");

Id与1和Name关联2.当使用属性时,有一些内置的“自己计算”代码,我应该在非属性API上公开 - 比如:

  • 按字母顺序
  • 序列化所有公共字段+属性
  • 按字母顺序
  • 序列化所有字段(公开或非公开)

然而:这两个都很容易用反射做。请注意,在任何一种情况下,如果类型可能在某些时候发生变化,使用反射是遇到问题的好方法。

可能有所帮助的其他功能,我可以提供更多信息:

  • 可以指定类型工厂(全局或每个实例),这对于预填充值或使用可用对象池非常有用
  • 代理类型可以为复杂的场景编写 - 当大多数模型工作正常时这很有用,但是一种类型太深奥,不适合序列化 - 但可以设计一个替代布局,您可以编写双向转换代码
  • 许多看起来像“元组”的东西将默认处理 - 特别是,如果它是公共不可变的,并且有一个构造函数接受与所有公共成员匹配的参数 - 它将假定序列化由构造函数
  • 指定的顺序

答案 2 :(得分:0)

另一个选项是Dasher(可通过NuGet获得)。

这是一个简单,快速,轻量级的.NET序列化器和反串行器,适用于C#类型,无需任何属性或其他装饰。

var stream = new MemoryStream();

// serialise to stream
new Serialiser<Holiday>().Serialise(stream, christmas);

stream.Position = 0;

// deserialise from stream
var christmas = new Deserialiser<Holiday>().Deserialise(stream);

它使用反射发射在运行时生成高度优化的序列化和反序列化功能。底层编码是MsgPack,它是自描述的,因此比线上的protobuf略大,但它确实意味着你可以解码你收到的任何消息,包括属性名称,类型和值。

免责声明:我写了这个库。