简体   繁体   English

使用MessagePack-Csharp nuget的多态性不适用于集合元素

[英]Polymorphism not working on collections elements using MessagePack-Csharp nuget

I'm not being able to deserialize a collection of elements where the instances have a Inheritance relationship between them. 我无法反序列化实例之间具有继承关系的元素集合。

Does anyone came across this issue? 有人遇到过这个问题吗?

So my use case is this: My model is similiar to this: 所以我的用例是这样的:我的模型与此类似:

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

And Items Collection is something like this: 而且Items Collection是这样的:

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

The setup that I have made to ensure the proper deserialization is: Defining the CollectionFormatterBase: 为确保正确的反序列化,我进行了以下设置:定义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);
        }
    }

The example that is not working, and not working I mean, the deserialized instances are all of base type, some how the inheritance relationship got lost in the serialization. 这个例子不起作用,也不起作用,我的意思是,反序列化的实例都是基本类型的,有些继承关系在序列化中是如何丢失的。

Example: 例:

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

                }

looking at the deserializedInstance Childs elements they all are from Item Type. 查看deserializedInstance Childs元素,它们都是来自Item Type。 Can you tell me what I'm doing wrong ? 你能告诉我我在做什么错吗? What is missing ? 什么东西少了 ?

A small update regarding Item definition: 关于项目定义的小更新:

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

This also does not work. 这也不起作用。 :( :(

Well looks like MessagePackSerializer static type as a static inner class called Typeless and that solve my problem: 看起来像MessagePackSerializer静态类型作为称为Typeless的静态内部类,可以解决我的问题:

With a instance of a ExtendedItem: 带有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 } })

            };

I was able to serialize that and deserialize with success ! 我能够序列化并成功反序列化!

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

                await fileManager.WriteAsync(bytes);

                ExtendedItem deserializedInstance = null;

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

despite the serialization and deserialization worked on .NET this sample did not work when deserializing in nodejs with msgpackjs package. 尽管在.NET上进行了序列化和反序列化,但使用msgpackjs包在nodejs中反序列化时,此示例仍无法正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 MessagePack-CSharp:使用泛型类型序列化属性 - MessagePack-CSharp: Serializing properties with generic types 如何将 MessagePack-CSharp 与字符串 JSON 一起使用? 不是 CLI,是 neuecc/MessagePack-CSharp - How to use MessagePack-CSharp with string JSON? Not is CLI, is neuecc/MessagePack-CSharp Azure Redis Messagepack-csharp 内存不足异常 - Azure Redis Messagepack-csharp Out of memory exception c# MessagePack-CSharp 所有公共成员必须标记KeyAttribute 或IgnoreMemberAttribute。 我的类型成员: - c# MessagePack-CSharp all public members must mark KeyAttribute or IgnoreMemberAttribute. MyType member: 为什么C ++ msgpack-c在数字10(0x0A)之前添加数字13(0x0D),而C#MessagePack-CSharp却没有? - Why C++ msgpack-c adds number 13 (0x0D) before number 10 (0x0A), but C# MessagePack-CSharp does not? 具有嵌套字典和多态性的MessagePack - MessagePack with nested Dictionary's and polymorphism Swashbuckle:多态性不适用于外部 nuget 包 - Swashbuckle: Polymorphism not working with external nuget package CMake CSharp 参考 nuget 包 - CMake CSharp reference nuget packges .Regex.IsMatch 无法使用 csharp 以 window 形式工作 - !Regex.IsMatch is not working in window form using csharp csharp中的datagridview填充不起作用 - datagridview population in csharp not working
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM