简体   繁体   English

使用 MessagePack 进行涉及继承的序列化后反射不正确

[英]Incorrect reflection after inheritance-involved serialization with MessagePack

I am serializing an Entity on a server:我在服务器上序列化一个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;
        }
    }

Every Entity has a Tile (which inherits from Component ).每个Entity都有一个Tile (继承自Component )。 Before serializing I check the type of the Tile and it returns World2D.ECS.Components.Tile .在序列化之前,我检查了Tile的类型,它返回World2D.ECS.Components.Tile

Then I send the serialized Entity to a client.然后我将序列化的Entity发送给客户端。

On the client I check reflection type of the component:在客户端我检查组件的反射类型:

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

After deserealizing Entity on the client, reflection returns World2D.ECS.Components.Component instead of World2D.ECS.Components.Tile .在客户端取消实现Entity后,反射返回World2D.ECS.Components.Component而不是World2D.ECS.Components.Tile

Update 1: Confirmed that this doesn't occur due to sending the serialized Entity over the.network because the bug occurs even if serializing and deserializing on the same machine.更新 1:确认这不会由于通过网络发送序列化Entity而发生,因为即使在同一台机器上序列化和反序列化也会出现错误。

https://github.com/neuecc/MessagePack-CSharp/issues/1405 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.默认情况下,消息包 stream 中不包含类型信息。添加类型信息的最佳方法是应用自述文件中描述的 [Union] 属性。 You might also find the Typeless resolver can solve your problem, but that comes with security implications and a larger data size.您可能还会发现 Typeless 解析器可以解决您的问题,但这会带来安全隐患和更大的数据量。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM