c# - 理解 Protobuf-net 属性的序列化和反序列化

标签 c# protobuf-net

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

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

最佳答案

出于序列化的目的,字典被视为列表。 您可以想象默认列表序列化类似于(假设有一个可用的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,这样如果testDictionarynullTestDictionary 返回null;如果 TestDictionary 设置null,则testDictionary 设置为null

关于c# - 理解 Protobuf-net 属性的序列化和反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43983076/

相关文章:

c# - 如何将 protobuf 序列化内容直接写入 SharpZipLib 流

protobuf-net - 是否可以在 Silverlight 中使用 protobuf-net 对私有(private)属性进行(反)序列化?

c# - VS2019 Winforms SDK风格的项目,无法添加新表单

C# Razor 重定向到 .Net Core 5 中具有自定义路由的页面

c# - 我希望我的 C# Windows 服务自动更新

c# - 使用 protobuf-net 在 WCF 中序列化数组

protocol-buffers - Protocol Buffer 如何处理版本控制?

c# - 从未知类调用已知属性

c# - 在 asp.net webform 中检测移动版本 - c#

c# - 具有 ProtoBuf.Meta 接口(interface)的模仿 ProtoEnumAttribute