Protobuf-net:带有包装器的锯齿状阵列

时间:2017-08-08 17:23:21

标签: c# protobuf-net

我知道protobuf-net不支持锯齿状数组,而包装器是一种解决方法。我试过测试它,序列化工作正常,但反序列化后没有任何错误,即反序列化后没有错误。

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
public class Source
{
    public Source()
    {
        List = new List<Dictionary<string, Item>>();
    }

    [ProtoIgnore]
    public List<Dictionary<string, Item>> List { get; set; }

    public List<DictionaryWrapper<string, Item>> ListProto
    {
        get
        {
            return List.ConvertAll(x => new DictionaryWrapper<string, Item>(x));
        }
        set
        {
            List = value.ConvertAll(x => x.Dictionary);
        }
    }
}

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
public class Item
{
    public string Value { get; set; }
}

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
public sealed class DictionaryWrapper<TKey, TValue>
{
    public DictionaryWrapper()
    {
    }

    public DictionaryWrapper(Dictionary<TKey, TValue> value)
    {
        Dictionary = value;
    }

    public Dictionary<TKey, TValue> Dictionary { get; set; }
}

序列化方法

    public void Test()
    {
        byte[] data = null;
        try
        {
            var source = new Source();

            for (var i = 0; i < 5; i++)
            {
                source.List.Add(new Dictionary<string, Item> {{i.ToString(), new Item {Value = i.ToString()}}});
            }

            using (var stream = new MemoryStream())
            {
                Serializer.Serialize(stream, source);
                data = stream.ToArray();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }

        Source result;
        using (var stream = new MemoryStream(data))
        {
             result = Serializer.Deserialize<Source>(stream);
        }

        Console.WriteLine(result.List.Count);
    }

更新:我找到了解决方法。所以这修复了反序列化,但仍然不知道为什么没有调用ListProto set

    [ProtoBeforeSerialization]
    public void ProtoBeforeSerialization()
    {
        List1Proto = List1.ConvertAll(x => new DictionaryWrapper<string, Item>(x));
    }

    [ProtoAfterDeserialization]
    public void ProtoAfterDeserialization()
    {
        List1 = List1Proto.ConvertAll(x => x.Dictionary);
    }

0 个答案:

没有答案