c# - 使用 ProtoBuf-net 反序列化派生类型(字典)未正确设置对象字段

标签 c# serialization protobuf-net deep-copy

我正在尝试序列化然后反序列化一个类派生自 Dictionary<string,int> 的对象带有一个字符串成员字段。

    public class TempClass : Dictionary<string, int>
    {
        public string Version;

        public TempClass() { }
    }

我已经编写了一个单元测试来捕获我遇到的问题:在使用 protobuf-net 进行序列化或反序列化(到/从 byte[])时,没有设置成员字段。此测试在最后失败 Assert在验证反序列化的 Version 时设置正确。它始终设置为 null而不是正确的 "someVersion" .

    [TestClass]
    public class serializationTest
    {
        [TestMethod]
        public void TestMethod1()
        {
            string newVersion = "someVersion";

            TempClass original = new TempClass()
            {
                {"a", 2},
                {"b", 3},
                {"c", 1},
            };
            original.Version = newVersion;

            byte[] serialized = Serialize(original);

            TempClass deserialized = Deserialize(serialized);

            // Validate
            foreach (var pair in original)
            {
                Assert.IsTrue(deserialized.ContainsKey(pair.Key));
                Assert.AreEqual(pair.Value, deserialized[pair.Key]);
            }

            Assert.AreEqual(newVersion, original.Version, "original mapping version not set correctly");
            Assert.AreEqual(newVersion, deserialized.Version, "deserialized version doesn't match");
        }

        private static TempClass Deserialize(byte[] serialized)
        {
            TempClass deserialized;
            using (MemoryStream ms = new MemoryStream())
            {
                ms.Write(serialized, 0, serialized.Length);
                ms.Position = 0;
                deserialized = Serializer.Deserialize<TempClass>(ms);
            }
            return deserialized;
        }

        private static byte[] Serialize(TempClass mapping)
        {
            byte[] serialized;
            using (MemoryStream ms = new MemoryStream())
            {
                Serializer.Serialize(ms, mapping);
                serialized = ms.ToArray();
            }
            return serialized;
        }
    }

我已经用 BinaryFormatter 尝试过同样的工作还有DataContractSerializer无济于事。有人可以帮我找出导致此测试失败的错误吗?

后续问题:如果我重新定义 TempClass像这样,总是调用构造函数而不是将成员字段正确设置为原始 Version .如何在构造函数不创建新的 Version 的情况下反序列化而不是只复制原始的?

    public class TempClass : Dictionary<string, int>
    {
        public string Version;

        public TempClass() 
        { 
            Version = DateTime.UtcNow.ToString("s");
        }
    }

最佳答案

这个效果可能与protobuf中IDictionary类型序列化的内部实现有关。 您可以在字典中添加版本数据或像此示例一样重写您的 dto 对象。 如果您使用此数据对象,它将修复您的测试:

[ProtoContract]
public class TempClass 
{
    [ProtoMember(1)]
    public Dictionary<string, int> data;

    [ProtoMember(2)]
    public string Version;

    public TempClass() { }
}

第三种方式是自己写连载。

关于c# - 使用 ProtoBuf-net 反序列化派生类型(字典)未正确设置对象字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26262098/

相关文章:

php在Mysql中序列化数据

protocol-buffers - Protobuf C# 消息翻译为 JAVA

c# - 如何解析最后包含 GMT 作为时区的日期时间字符串?

.net - 无法在 VB.NET 中的可序列化单例类的实例上调用 Serialize()

c# - 如何用派生类序列化基类

.net - protobuf-net 的替代方案 - 使用对象图的大小和时间高效的序列化程序

c# - 在 protobuf-net 中序列化 Type 类?

c# - 使用 asp.net 和 C# 从 javascript 调用外部服务器上的 webservice

c# - Linq-to-SQL 帮助 - 选择重复行

c# - 启动后立即执行计时器?