【问题标题】:Protobuf-Net always deserializes an empty listProtobuf-Net 总是反序列化一个空列表
【发布时间】:2014-07-21 11:21:54
【问题描述】:

以下代码显示了我如何尝试使用 Protobuf-Net 序列化/反序列化列表。方法getNewItem()返回一个ItemsStore的对象,添加到List中。

// Create an empty list
private ItemsStoreList text;

// Add some elements to the list
lock (text.SyncRoot)
{
    text.AddItem(getNewItem());
    text.AddItem(getNewItem());
    text.AddItem(getNewItem());
}

// Serialize
var file = File.Create("testfile.bin");
Serializer.Serialize<ItemsStoreList>(file, text);

// Deserialize
ItemsStoreList textNew = Serializer.Deserialize<ItemsStoreList>(file);

运行此代码后,对象textNew 中包含的列表始终为空。对象textNew从类ItemsStoreList实例化,如下所示:

[ProtoContract]
public class ItemsStoreList
{
    [ProtoMember(1)]
    private List<ItemsStore> m_listData;

    private readonly object m_SyncRoot = new object();

    public ItemsStoreList()
    {
        m_listData = new List<ItemsStore>();
    }

    public void AddItem(ItemsStore item)
    {
        m_listData.Add(item);
    }

    public object SyncRoot
    {
        get { return this.m_SyncRoot; }
    }

    public int Count
    {
        get { return m_listData.Count; }
    }

    public ItemsStore getItem(int idx)
    {
        return (ItemsStore)m_listData[idx];
    }

    public void Clear()
    {
        m_listData.Clear();
    }
}

[ProtoContract]
public class ItemsStore
{
    [ProtoMember(1)]
    public myStruct m_Text;
    [ProtoMember(2)]
    public ulong m_Time;

    public ItemsStore(myStruct newText, ulong newTime)
    {
        m_Text = newText;
        m_Time = newTime;
    }

    public myStruct Text
    {
        get { return m_Text; }
    }

    public ulong Time
    {
        get { return m_Time; }
    }
}

[ProtoContract]
public struct myStruct
{
    [ProtoMember(1)]
    public uint var1;

    [ProtoMember(2)]
    public byte var2;

    [ProtoMember(3)]
    public byte[] var3;

    [ProtoMember(4)]
    public string var4;
}

【问题讨论】:

  • 只是额外的,但请注意,“可变结构”实际上比您想象的更容易解决,这要归功于 protobuf-net 的自动元组处理:如果类型没有 proto 属性,但有具有与公共成员完全匹配的参数的构造函数,它假定构造函数演示了意图;例如:pastie.org/9409395

标签: c# serialization protobuf-net


【解决方案1】:

我注意到的第一件事是你没有倒带;添加这个(在序列化和反序列化之间)会改变行为:

file.Position = 0;

我们现在得到一个与 ItemsStore 构造函数相关的异常,因此我们可以指示 protobuf-net 完全忽略该构造函数:

[ProtoContract(SkipConstructor = true)]
public class ItemsStore

现在我们得到了 3 件物品:

System.Console.WriteLine(textNew.Count);

哪个输出:

3

进一步探测表明它很可能也在获取其他数据:

for (int i = 0; i < textNew.Count; i++)
{
    var item = textNew.getItem(i);
    System.Console.WriteLine(item.m_Text.var1);
    System.Console.WriteLine(item.m_Time);
}

不过,我将添加关于可变结构和公共字段的强制性警告。

【讨论】:

    猜你喜欢
    • 2011-01-23
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 2012-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多