了解Protobuf-net序列化和属性的反序列化

时间:2017-05-15 15:17:01

标签: c# protobuf-net

我正在使用Protobuf-net序列化程序进行一些测试,并且正在尝试使用属性的序列化。基本上我想将字典(string,int)存储为字典(字符串,字符串),然后在反序列化时将(字符串,字符串)转换回(字符串,整数)。然而,令我惊讶的是,它在反序列化时通过TestDictionary上的getter(然后抛出一个空引用异常)让我很困惑。我认为它通过反序列化的设定者来完成。所以,基本上我不确定属性序列化应该如何运作。我写的简单测试类如下:

[ProtoContract]
public class Class1
{
    [ProtoMember(2)]
    public int test;
    public Dictionary<string, int> testDictionary;
    //public Dictionary<string, string> testDictionaryString;
    [ProtoMember(3)]
    private string test2;
    [ProtoMember(4)]
    private string test3;
    [ProtoMember(5)]
    private string test4;

    public Class1()
        {}

    public Class1(int test)
    {
        this.test = test;
            this.testDictionary = new Dictionary<string, int>();
        for (int i = 0; i < test; i++)
        {
            this.testDictionary.Add("a" + i.ToString(), i);
        }
        test2 = (test + 1).ToString();
        test3 = (test + 2).ToString();
        test4 = (test + 3).ToString();
    }

    [ProtoMember(1)]
    public Dictionary<string, string> TestDictionary
    {
        get
        {
            Dictionary<string, string> temp = new Dictionary<string, string>();
            foreach (KeyValuePair<string, int> pair in this.testDictionary)
            {
                temp.Add(pair.Key, pair.Value.ToString());
            }
            return temp;
        }
        set
        {
            testDictionary = new Dictionary<string, int>();
            foreach (KeyValuePair<string, string> pair in value)
            {
                testDictionary.Add(pair.Key, Convert.ToInt32(pair.Value));
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

出于序列化的目的,字典被视为列表。 您可以想象默认列表序列化(假设有set可用):

var list = obj.TheProperty;
if(list == null) {
    list = new TheListType();
    obj.TheProperty = list;
}
do {
    list.Add(DeserializeTheItemType(reader));
} while ({still that field})

但是,你可以影响它。只需添加OverwriteTrue = true即可满足您的需求:

[ProtoMember(1, OverwriteList = true)]
public Dictionary<string, string> TestDictionary {...}

现在应该做更多的事情:

var list = new TheListType();
do {
    list.Add(DeserializeTheItemType(reader));
} while ({still that field})
obj.TheProperty = list;

然而,重要的结果是,Merge将不再按照通常的预期方式运作。

作为旁注:您的get / set可能应该通过null,因此如果testDictionarynull,{{1} } return TestDictionary;如果null 设置TestDictionary,则null设置为testDictionary