c#ProtoBuf序列化程序的新类型

本文关键字:类型 新类型 序列化 程序 c#ProtoBuf | 更新日期: 2023-09-27 18:21:12

我正在使用Protobuf-net来替换我的DataContractSerializer,但是否可以发送其他对象类型,如ColorSizePoint等等?因为这在DataContractSerializer。我在文件中找不到它。

c#ProtoBuf序列化程序的新类型

首先,请注意,批量类型可以作为"元组"自动处理;例如,我希望System.Windows.Point工作良好,因为它只有XY,并且它有一个接受xy的构造函数。不幸的是,System.Drawing.PointXYIsEmpty,还有一个接受xy的构造函数,所以它不能自动推断出对System.Drawing.Point的正确处理,但我试图指出的一点是:一些外部类型将在没有任何额外工作的情况下工作。

对于其余部分,有多种方法可以使用RuntimeTypeModel API来解决域模型之外的类型问题。根据具体类型,可以选择:

  • 告诉它您希望它如何根据其成员序列化该类型
  • 为该类型编写一个代理(使用适当的转换运算符),并告诉它代理的情况

例如:

RuntimeTypeModel.Default.Add(typeof(System.Drawing.Point), false)
                        .Add("X", "Y");

其将X配置为字段1、将Y配置为字段2。代理方法对于复杂的场景更有用,但作为一个微不足道的例子:

[ProtoContract]
public class PointDto
{
    [ProtoMember(1)] public int X { get; set; }
    [ProtoMember(2)] public int Y { get; set; }
    public static implicit operator System.Drawing.Point(PointDto value)
    {
        return value == null
            ? System.Drawing.Point.Empty
            : new System.Drawing.Point(value.X, value.Y);
    }
    public static implicit operator PointDto(System.Drawing.Point value)
    {
        return new PointDto { X = value.X, Y = value.Y };
    }
}

然后:

RuntimeTypeModel.Default.Add(typeof(System.Drawing.Point), false)
                        .SetSurrogate(typeof(PointDto));

使用这个配置,库将根据需要转换为代理类型/从代理类型转换-其想法是,您可以在operator中添加所需的任何代码,从而使DTO能够非常简单且易于序列化。

最后,请注意,许多类型将具有与其ToString实现一起工作的Parse API;如果您想启用Parse方法(作为最后的努力将其序列化为字符串),那么:

RuntimeTypeModel.Default.AllowParseableTypes = true;