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

How to deserialize generic dictionary with object value in protobuf-net using a proxy/shim property?

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);
    }
}

图书馆class

[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)。我想将类型动态转换为我需要的类型。

我缺少什么才能让 proxy/shim 属性 KeeperSer 的 setter 工作?

通过测试,似乎任何 IEnumerable<object> 兼容类型都不能以任何方式与 Protobuf-net 一起工作,因为它根本不知道如何处理它。即使没有抛出错误,这些类型的 setter 也永远不会被调用。除此之外,使用 'cheat' 的通用代理 implicit operator 在 Protobuf-net 中提供递归循环。

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