【问题标题】:c# ProtoBuf serializer new typesc# ProtoBuf 序列化器新类型
【发布时间】:2013-07-05 07:49:01
【问题描述】:

我正在使用 Protobuf-net 来替换我的 DataContractSerializer,但是否可以发送其他对象类型,例如 ColorSizePoint 甚至更多?因为DataContractSerializer 可以做到这一点。我在文档中找不到它。

【问题讨论】:

    标签: c# serialization protobuf-net


    【解决方案1】:

    首先,请注意很多种类型可以作为“元组”自动处理;例如,我希望System.Windows.Point 可以正常工作,因为它只有一个XY,并且它有一个接受xy 的构造函数。不幸的是,System.Drawing.PointXYIsEmpty,以及一个接受xy 的构造函数,所以它不能自动推断出System.Drawing.Point 的正确处理方式——但是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));
    

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

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

    RuntimeTypeModel.Default.AllowParseableTypes = true;
    

    【讨论】:

      猜你喜欢
      • 2012-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-30
      • 2021-10-15
      相关资源
      最近更新 更多