[英]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.