多态性不使用MessagePack-Csharp nuget处理集合元素

时间:2018-05-15 15:54:13

标签: c# serialization msgpack

我无法反序列化实例之间具有继承关系的元素集合。

有没有人遇到过这个问题?

所以我的用例是这样的: 我的模型与此类似:

[DataContract]
    public class Item
    {
        [DataMember]
        public int Id { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public bool Valid { get; set; }


    }

    [DataContract]
    public class IntermediateItem : Item
    {
        [DataMember]
        public int Priority { get; set; }
    }

    [DataContract]
    public class ExtendedItem : IntermediateItem
    {
        [DataMember]
        public int Count { get; set; }

        [DataMember]
        public ItemsCollection Childs { get; set; }
    }

物品收集是这样的:

 [DataContract]
    public class ItemsCollection : Collection<Item>
    {
     }

我为确保正确的反序列化而进行的设置是: 定义CollectionFormatterBase:

 public class ItemCollectionFormatterBase : CollectionFormatterBase<Item, ItemsCollection>
    {
        protected override ItemsCollection Create(int count)
        {
            return new ItemsCollection();
        }

        protected override void Add(ItemsCollection collection, int index, Item value)
        {
            collection.Add(value);
        }
    }

不工作但不工作的示例我的意思是,反序列化的实例都是基类型,一些是如何在序列化中丢失继承关系。

示例:

   MessagePack.Resolvers.CompositeResolver.RegisterAndSetAsDefault(new[] { new ItemCollectionFormatterBase() }, new[] { StandardResolver.Instance });


ExtendedItem instance = new ExtendedItem()
            {
                Id = 1,
                Name = "Extended Item",
                Priority = 121,
                Valid = true,
                Count = 10,
                Childs = new ItemsCollection(new List<Item>() { new Item() { Id = 1 }, new IntermediateItem() { Priority = 10 }, new ExtendedItem() { Count = 10 } })

            };

 byte[] bytes  = MessagePackSerializer.Serialize(instance);

          using (FileStream file = new FileStream(this.filePath.AbsolutePath, FileMode.Create))
            {
                await file.WriteAsync(bytes  , 0, payload.Length);
                await file.FlushAsync();
            }

  using (FileStream file = new FileStream(testsFolder + @"\ExtendedItem.msgPack-csharp.dat", FileMode.Open))
                {

                    file.Seek(0, SeekOrigin.Begin);
                    deserializedInstance =  MessagePackSerializer.Deserialize<ExtendedItem>(file);

                }

查看deserializedInstance Childs元素,它们都来自Item Type。 你能告诉我我做错了什么吗?缺少什么?

关于项目定义的小更新:

 [DataContract]  
    [KnownType(typeof(IntermediateItem))]
    [KnownType(typeof(ExtendedItem))]
    public class Item
    {
        [DataMember]
        public int Id { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public bool Valid { get; set; }
    }

这也行不通。 :(

1 个答案:

答案 0 :(得分:0)

看起来像MessagePackSerializer静态类型作为一个名为Typeless的静态内部类,它解决了我的问题:

使用ExtendedItem的实例:

  ExtendedItem instance = new ExtendedItem()
            {
                Id = 1,
                Name = "Extended Item",
                Priority = 121,
                Valid = true,
                Count = 10,
                Childs = new ItemsCollection(new List<Item>() { new Item() { Id = 1 }, new IntermediateItem() { Priority = 10 }, new ExtendedItem() { Count = 10 } })

            };

我能够序列化并成功反序列化!

 byte[] bytes = MessagePackSerializer.Typeless.Serialize(instance);

                await fileManager.WriteAsync(bytes);

                ExtendedItem deserializedInstance = null;

                deserializedInstance = MessagePackSerializer.Typeless.Deserialize(bytes) as ExtendedItem;

尽管在.NET上进行了序列化和反序列化,但在使用msgpackjs包对nodejs进行反序列化时,此示例无效。