使用 protobuf-net 合并 Collection 属性对象

Posted

技术标签:

【中文标题】使用 protobuf-net 合并 Collection 属性对象【英文标题】:Merging Collection property objects using protobuf-net 【发布时间】:2011-03-26 15:15:15 【问题描述】:

尝试使用 protobuf-net Merge 保存和恢复对象。 我可以让简单的对象工作,但我无法让集合属性对象合并。 感谢 protobuf-net 专家的任何帮助。

working code:

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using ProtoBuf;
class Program

    static void Main(string[] args)
    
        ChildTest();
        ParentTest();

        Console.Write("Press any key to continue...");
        Console.ReadKey();
    

    private static void ChildTest()
    
        Console.WriteLine("ChildTest:");
        var child = new Child() Name = "OriginalName";

        var stream = new MemoryStream();
        Serializer.Serialize(stream, child);
        var tempChild = Serializer.Deserialize<Child>(new MemoryStream(stream.ToArray()));
        tempChild.Name = "MergedName";

        var stream1 = new MemoryStream();
        Serializer.Serialize(stream1, tempChild);
        child = Serializer.Deserialize<Child>(new MemoryStream(stream1.ToArray()));
        Console.WriteLine(child.Name + " - MergedName as expected");
    

    private static void ParentTest()
    
        Console.WriteLine("ParentTest:");
        var child = new Child() Name = "OriginalName";
        var parent = new Parent Items = new List<Child>(1);
        parent.Items.Add(child);

        var stream = new MemoryStream();
        Serializer.Serialize(stream,parent);
        var tempParent = Serializer.Deserialize<Parent>(new MemoryStream(stream.ToArray()));
        tempParent.Items[0].Name = "MergedName";

        var stream1 = new MemoryStream();
        Serializer.Serialize(stream1, tempParent);
        parent = Serializer.Merge(new MemoryStream(stream1.ToArray()), parent);
        Console.WriteLine(parent.Items[0].Name + " - MergedName expected here");

        Parent nullParent = null;
        nullParent = Serializer.Merge(new MemoryStream(stream1.ToArray()), nullParent);
        Console.WriteLine(nullParent.Items[0].Name+ " - MergedName as expected for null");
    


[ProtoContract] //, ProtoInclude(2, typeof(Child[]))
public partial class Parent : ISerializable

    public Parent()  

    [ProtoMember(1)]
    public List<Child> Items  get; set; 

    protected Parent(SerializationInfo info, StreamingContext context)
    
        Serializer.Merge<Parent>(info, this);
    
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    
        Serializer.Serialize(info, this);
    


[ProtoContract]
public partial class Child : ISerializable

    public Child()  

    [ProtoMember(1)]
    public string Name  get; set; 

    protected Child(SerializationInfo info, StreamingContext context)
    
        Serializer.Merge<Child>(info, this);
    
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    
        Serializer.Serialize(info, this);
    

显然,protobuf-net 无法做到这一点, - 有什么方法可以做我想做的事情吗?即覆盖重复的属性?也许是另一个图书馆?

【问题讨论】:

【参考方案1】:

这是预期的功能;合并 singular 属性确实会用合并流中的值覆盖属性;但是,对于 repeated 属性(列表、数组等),行为(根据更广泛的“protobuf”系列实现)是从合并流到列表。

你会发现:

    Console.WriteLine(parent.Items[0].Name); // prints OriginalName
    Console.WriteLine(parent.Items[1].Name) // prints MergedName

具体来说,它按位置逐项合并。

【讨论】:

谢谢 Marc,我希望能直接从你那里得到答复。有什么方法可以做我想做的事吗?即覆盖重复的属性。

以上是关于使用 protobuf-net 合并 Collection 属性对象的主要内容,如果未能解决你的问题,请参考以下文章

protobuf-net 版本容差

hive中多行合并一行concat_ws(去重及不去重)

使用protobuf-net继承时如何选择字段号?

如何使用 protobuf-net 处理 .proto 文件

如何使用 protobuf-net 读回附加的对象?

protobuf-net 使用啥基本序列化器来输出字节数组?