c#ProtoBuf序列化器新类型

时间:2013-07-05 07:49:02

标签: c# serialization protobuf-net

我使用 Protobuf-net 替换我的DataContractSerializer,但是是否可以发送其他对象类型,例如ColorSize,{{1还有更多?因为Point可以实现这一点。我在文档中找不到它。

1 个答案:

答案 0 :(得分:2)

首先请注意, lot 类型可以自动处理为“元组”;例如,我希望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非常简单且易于序列化。

最后,请注意,许多类型的Parse API都适用于ToString实施;如果你想使用Parse方法(序列化为字符串作为最后努力),那么:

RuntimeTypeModel.Default.AllowParseableTypes = true;