使用 MessagePack 进行涉及继承的序列化后反射不正确
Incorrect reflection after inheritance-involved serialization with MessagePack
我正在服务器上序列化一个 Entity
:
public class Entity
{
private List<Component> _components = new List<Component>();
[Key(0)]
public List<Component> Components {
get {
return _components;
}
set
{
_components = value;
}
}
public T GetComponent<T>() where T : Component
{
foreach (Component component in _components)
{
var componentType = component.GetType();
Debug.WriteLine(componentType);
if (componentType.Equals(typeof(T)))
{
return (T)component;
}
}
return null;
}
}
[MessagePackObject]
public class Component
{
[IgnoreMember]
public Entity entity;
}
[MessagePackObject]
public class Tile : Component
{
public enum TileType
{
Soil,
Mud,
}
[Key(0)]
public TileType Type { get; set; }
public Tile(TileType type)
{
Type = type;
}
}
每个 Entity
都有一个 Tile
(继承自 Component
)。在序列化之前,我检查了 Tile
的类型,它 returns World2D.ECS.Components.Tile
.
然后我将序列化的 Entity
发送给客户。
在客户端我检查组件的反射类型:
public T GetComponent<T>() where T : Component
{
foreach (Component component in _components)
{
var componentType = component.GetType();
Debug.WriteLine(componentType); // returns World2D.ECS.Components.Component instead of World2D.ECS.Components.Tile as on the server
if (componentType.Equals(typeof(T)))
{
return (T)component;
}
}
return null;
}
在客户端反序列化 Entity
后,反射 returns World2D.ECS.Components.Component
而不是 World2D.ECS.Components.Tile
.
更新 1:确认这不会由于通过网络发送序列化 Entity
而发生,因为即使在同一台机器上序列化和反序列化也会出现错误。
https://github.com/neuecc/MessagePack-CSharp/issues/1405
By default, type information is not included in the messagepack stream. The best way to add type information is to apply the [Union] attribute as described in the readme. You might also find the Typeless resolver can solve your problem, but that comes with security implications and a larger data size.
我正在服务器上序列化一个 Entity
:
public class Entity
{
private List<Component> _components = new List<Component>();
[Key(0)]
public List<Component> Components {
get {
return _components;
}
set
{
_components = value;
}
}
public T GetComponent<T>() where T : Component
{
foreach (Component component in _components)
{
var componentType = component.GetType();
Debug.WriteLine(componentType);
if (componentType.Equals(typeof(T)))
{
return (T)component;
}
}
return null;
}
}
[MessagePackObject]
public class Component
{
[IgnoreMember]
public Entity entity;
}
[MessagePackObject]
public class Tile : Component
{
public enum TileType
{
Soil,
Mud,
}
[Key(0)]
public TileType Type { get; set; }
public Tile(TileType type)
{
Type = type;
}
}
每个 Entity
都有一个 Tile
(继承自 Component
)。在序列化之前,我检查了 Tile
的类型,它 returns World2D.ECS.Components.Tile
.
然后我将序列化的 Entity
发送给客户。
在客户端我检查组件的反射类型:
public T GetComponent<T>() where T : Component
{
foreach (Component component in _components)
{
var componentType = component.GetType();
Debug.WriteLine(componentType); // returns World2D.ECS.Components.Component instead of World2D.ECS.Components.Tile as on the server
if (componentType.Equals(typeof(T)))
{
return (T)component;
}
}
return null;
}
在客户端反序列化 Entity
后,反射 returns World2D.ECS.Components.Component
而不是 World2D.ECS.Components.Tile
.
更新 1:确认这不会由于通过网络发送序列化 Entity
而发生,因为即使在同一台机器上序列化和反序列化也会出现错误。
https://github.com/neuecc/MessagePack-CSharp/issues/1405
By default, type information is not included in the messagepack stream. The best way to add type information is to apply the [Union] attribute as described in the readme. You might also find the Typeless resolver can solve your problem, but that comes with security implications and a larger data size.