如何使用proxy / shim属性在protobuf-net中使用对象值反序列化通用字典?

时间:2016-11-23 09:34:43

标签: c# object dictionary protobuf-net

I've tried using the solutions in this post. Both the property and the surrogate didn't work. The cause would most likely be that protobuf-net doesn't work on dictionary directly but serializes the types a dictionary contains (and a surrogate on object is impossible).

我的测试代码

class Program
{
    static void Main(string[] args)
    {
        var library = new Library();
        library.Keeper.Add("Harry Potter", "blablabla text... text...");
        library.Keeper.Add("Other book", "Awesome story.");

        // Write and read to test serializing.
        Library deserialize;
        using (var ms = new MemoryStream())
        {
            Serializer.Serialize(ms, library);

            ms.Flush();
            ms.Position = 0;

            deserialize = Serializer.Deserialize<Library>(ms);
        }

        Console.WriteLine(deserialize.Keeper.Count);
    }
}

图书馆类

[ProtoContract]
public class Library
{
    public Dictionary<string, object> Keeper { get; set; }

    [ProtoMember(1)]
    public Dictionary<string, string> KeeperSer
    {
        get
        {
            var res = new Dictionary<string, string>();
            foreach (var pair in Keeper)
            {
                res.Add(pair.Key, TypeDescriptor.GetConverter(pair.Value.GetType()).ConvertToInvariantString(pair.Value));
            }
            return res;
        }
        set
        {
            var set = new Dictionary<string, object>();
            foreach (var pair in value)
            {
                set.Add(pair.Key, pair.Value);
            }
            Keeper = set;
        }
    }

    public Library()
    {
        Keeper = new Dictionary<string, object>();
    }
}

我也尝试将[ProtoIgnore]添加到Keeper属性中。在KeeperSerKeeper的setter处添加断点在运行项目时永远不会触发。 getter确实有效,数据由protobuf-net写入MemoryStream。将新项目添加到Library时,长度也会有所不同。

Dictionary<string, object>的原因是我在另一个项目中使用TypeDescriptor.GetConverter(Type)。我想动态地将类型转换为我需要的类型。

我缺少什么使代理/填充属性KeeperSer的setter工作?

1 个答案:

答案 0 :(得分:0)

通过测试似乎任何IEnumerable<object>兼容类型都不会以任何方式与Protobuf-net一起工作,因为它根本不知道如何处理它。即使没有抛出错误,也不会调用这些类型的setter。除此之外,使用通用代理来“欺骗”implicit operator在Protobuf-net内部给出一个递归循环。

目前,我认为我需要只存储对象数据的文本表示(Dictionary<string,string>),而不要将Dictionary<string,object>与Protobuf-net序列化程序结合使用。