Protobuf-net - 具有父引用的对象列表

时间:2014-06-09 17:01:27

标签: list reference protobuf-net

我有一个简单的类,引用了父对象。所有对象都在一个列表中(甚至是父对象)。反序列化后是否可以保留引用引用?

在我的代码中,我有类似的东西:

    [ProtoContract]
    public class ProtoItem
    {
        [ProtoMember(1)]
        public int Value { get; set; }

        [ProtoMember(2, AsReference = true)]
        public ProtoItem BaseItem { get; set; }
    }

主要看起来像这样:

        static void Main()
        {
            var itemParent = new ProtoItem { Value = 1 };
            var item2 = new ProtoItem { Value = 2, BaseItem = itemParent };
            var item3 = new ProtoItem { Value = 3, BaseItem = itemParent };

            var parentListToWrite = new List<ProtoItem> {itemParent, item2, item3};

            const string file = "protofile.txt";
            try { File.Delete(file); }
            catch { };

            using (var fs = File.OpenWrite(file)) { Serializer.Serialize(fs,    
                 parentListToWrite); }

        List<ProtoItem> readList;
        using (var fs = File.OpenRead(file)) { readList = 
            Serializer.Deserialize<List<ProtoItem>>(fs); }

        if (readList[0] == readList[2].BaseItem)
        {
            //how to make it equal?
        }
        if (readList[0] == readList[1].BaseItem)
        {
            //how to make it equal?
        }
    }

如果条件有效,是否可以反序列化?

1 个答案:

答案 0 :(得分:1)

protobuf规范没有对象标识的概念。 protobuf-net (作为一个可选的启用功能),但它目前不能直接用于列表项,尽管我怀疑它可能应该。但是,由于它会破坏格式,如果我修复它,则需要显式启用。

但是下面的代码今天起作用了 - 请注意我在这里所做的是将顶级列表项包装在一个封装ProtoItem的包装器中,但这样做可以启用引用跟踪。不理想,但是:它有效。

using ProtoBuf;
using System.Collections.Generic;
using System.IO;

[ProtoContract(AsReferenceDefault=true)]
public class ProtoItem
{
    [ProtoMember(1)]
    public int Value { get; set; }

    [ProtoMember(2)]
    public ProtoItem BaseItem { get; set; }
}
[ProtoContract]
public class Wrapper
{
    [ProtoMember(1, DataFormat = DataFormat.Group)]
    public ProtoItem Item { get;set; }

    public static implicit operator ProtoItem(Wrapper value)
    {
        return value == null ? null : value.Item;
    }
    public static implicit operator Wrapper(ProtoItem value)
    {
        return value == null ? null : new Wrapper { Item = value };
    }
}



static class Program
{

    static void Main()
    {
        var itemParent = new ProtoItem { Value = 1 };
        var item2 = new ProtoItem { Value = 2, BaseItem = itemParent };
        var item3 = new ProtoItem { Value = 3, BaseItem = itemParent };

        var parentListToWrite = new List<Wrapper> { itemParent, item2, item3 };

        const string file = "protofile.txt";
        try
        { File.Delete(file); }
        catch
        { };

        using (var fs = File.OpenWrite(file))
        {
            Serializer.Serialize(fs,
    parentListToWrite);
        }

        List<Wrapper> readList;
        using (var fs = File.OpenRead(file))
        {
            readList = Serializer.Deserialize<List<Wrapper>>(fs);
        }

        if (readList[0].Item == readList[2].Item.BaseItem)
        {
            //how to make it equal?
            System.Console.WriteLine("eq");
        }
        if (readList[0].Item == readList[1].Item.BaseItem)
        {
            //how to make it equal?
            System.Console.WriteLine("eq");
        }
    }
}