"is not registered in resolver" 使用 MessagePack 以抽象 class 序列化时出现异常
"is not registered in resolver" exception when serializing with abstract class using MessagePack
正在尝试序列化 componentMappers
。异常抛出在 .Serialize()
:
var componentMappers = new Bag<ComponentMapper>();
var componentMappersS = MessagePackSerializer.Serialize(componentMappers);
var componentMappersD = MessagePackSerializer.Deserialize<Bag<ComponentMapper>>(componentMappersS);
FormatterNotRegisteredException: MonoGame.Extended.Entities.ComponentMapper is not registered in resolver: MessagePack.Resolvers.StandardResolver
[MessagePackObject]
public abstract class ComponentMapper
{
[SerializationConstructor]
protected ComponentMapper(int id, Type componentType)
{
Id = id;
ComponentType = componentType;
}
[Key(0)]
public int Id { get; set; }
[Key(2)]
public Type ComponentType { get; }
public abstract bool Has(int entityId);
public abstract void Delete(int entityId);
}
[MessagePackObject]
public class ComponentMapper<T> : ComponentMapper
where T : class
{
private readonly Action<int> _onCompositionChanged;
// Custom
[SerializationConstructor]
public ComponentMapper(int id, Bag<T> components) : base(id, typeof(T))
{
Id = id;
Components = components;
}
}
public class Bag<T> : IEnumerable<T>
{
[Key(0)]
public T[] _items;
[Key(1)]
public bool _isPrimitive;
[IgnoreMember]
public int Capacity => _items.Length;
[IgnoreMember]
public bool IsEmpty => Count == 0;
[IgnoreMember]
public int Count { get; private set; }
// Custom
[SerializationConstructor]
public Bag(T[] _items, bool _isPrimitive)
{
this._isPrimitive = _isPrimitive;
this._items = _items;
}
}
尽管如果针对特定类型进行序列化,即:
var componentMapper = new ComponentMapper<Human>(0, new Bag<Human>());
var componentMapperS = MessagePackSerializer.Serialize(componentMapper);
var componentMapperD = MessagePackSerializer.Deserialize<ComponentMapper<Human>>(componentMapperS);
没有问题。
发生这种情况是因为 ComponentMapper
是 abstract
,所以我必须使用 MessagePack
s Union
。 MessagePack 尝试序列化抽象 class 但它不知道“在它下面”到底是什么类型,因此您必须用 Union
.
标记可能的候选对象
正在尝试序列化 componentMappers
。异常抛出在 .Serialize()
:
var componentMappers = new Bag<ComponentMapper>();
var componentMappersS = MessagePackSerializer.Serialize(componentMappers);
var componentMappersD = MessagePackSerializer.Deserialize<Bag<ComponentMapper>>(componentMappersS);
FormatterNotRegisteredException: MonoGame.Extended.Entities.ComponentMapper is not registered in resolver: MessagePack.Resolvers.StandardResolver
[MessagePackObject]
public abstract class ComponentMapper
{
[SerializationConstructor]
protected ComponentMapper(int id, Type componentType)
{
Id = id;
ComponentType = componentType;
}
[Key(0)]
public int Id { get; set; }
[Key(2)]
public Type ComponentType { get; }
public abstract bool Has(int entityId);
public abstract void Delete(int entityId);
}
[MessagePackObject]
public class ComponentMapper<T> : ComponentMapper
where T : class
{
private readonly Action<int> _onCompositionChanged;
// Custom
[SerializationConstructor]
public ComponentMapper(int id, Bag<T> components) : base(id, typeof(T))
{
Id = id;
Components = components;
}
}
public class Bag<T> : IEnumerable<T>
{
[Key(0)]
public T[] _items;
[Key(1)]
public bool _isPrimitive;
[IgnoreMember]
public int Capacity => _items.Length;
[IgnoreMember]
public bool IsEmpty => Count == 0;
[IgnoreMember]
public int Count { get; private set; }
// Custom
[SerializationConstructor]
public Bag(T[] _items, bool _isPrimitive)
{
this._isPrimitive = _isPrimitive;
this._items = _items;
}
}
尽管如果针对特定类型进行序列化,即:
var componentMapper = new ComponentMapper<Human>(0, new Bag<Human>());
var componentMapperS = MessagePackSerializer.Serialize(componentMapper);
var componentMapperD = MessagePackSerializer.Deserialize<ComponentMapper<Human>>(componentMapperS);
没有问题。
发生这种情况是因为 ComponentMapper
是 abstract
,所以我必须使用 MessagePack
s Union
。 MessagePack 尝试序列化抽象 class 但它不知道“在它下面”到底是什么类型,因此您必须用 Union
.