C# fastJSON反序列化列表

C# fastJSON反序列化列表,c#,json,serialization,unity3d,fastjson,C#,Json,Serialization,Unity3d,Fastjson,这是基于我之前的一个问题。我试图保存一个蓝图,它只是一堆游戏对象/实体的设置。我现在将组件(及其设置)存储为一个列表(IEntityComponent是任何组件的接口),包装在一个名为ComponentTable的类中。我只想序列化列表,所有私有内容都不会序列化,只是为了更快地查找(以内存为代价)。这可以正确地序列化,甚至可以无错误地反序列化,但是我注意到componentTable没有正确地反序列化 它创建ComponentTable的一个实例,但从未实际向其添加值。因此,它不是包含Camer

这是基于我之前的一个问题。我试图保存一个蓝图,它只是一堆游戏对象/实体的设置。我现在将组件(及其设置)存储为一个列表(IEntityComponent是任何组件的接口),包装在一个名为ComponentTable的类中。我只想序列化列表,所有私有内容都不会序列化,只是为了更快地查找(以内存为代价)。这可以正确地序列化,甚至可以无错误地反序列化,但是我注意到componentTable没有正确地反序列化

它创建ComponentTable的一个实例,但从未实际向其添加值。因此,它不是包含CameraComponent、VelocityComponent和InputComponent的组件表,而是一个空的组件表

{
 "$types" : {
  "ECS.Framework.Collections.Blueprint, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" : "1",
  "ECS.Features.Core.CameraComponent, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" : "2",
  "ECS.Features.Core.VelocityComponent, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" : "3",
  "InputComponent, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" : "4"
 },
 "$type" : "1",
 "Components" : [
  {
     "$type" : "2",
     "Tag" : "MainCamera",
     "Test" : "0, 0, 0",
     "BackgroundColour" : "0, 0, 1, 1",
     "ViewportRect" : "10, 10 : 10, 10",
     "Orthographic" : false,
     "FieldOfView" : 60,
     "OrthoSize" : 5,
     "Depth" : 0,
     "OcclusionCulling" : true,
     "HDR" : false,
     "Enabled" : true
  },
  {
     "$type" : "3",
     "Enabled" : true,
     "CurrentVelocity" : "0, 0, 0"
  },
  {
     "$type" : "4",
     "TEST" : 0,
     "Enabled" : true
  }
 ],
 "Children" : [

 ],
 "Parent" : ""
}
这就是它保存的方式,所以看起来它保存的是正确的。我只控制向量、Rect和colors的序列化/序列化,因为任何单位值类型都会导致错误

我相信它是正确序列化的,但由于某些原因,它没有反序列化到componentTable中。有人知道fastJSON在这种继承(使类从列表继承)方面是否有问题吗

理想情况下,我会将其作为Dictionary继承,但fastJSON不会序列化该类型,只将其保存为“System.Mono”,然后在序列化时导致错误

编辑:以下是blueprint和component表类

public sealed class Blueprint 
{
    public ComponentTable Components { get; private set; }

    public List<string> Children { get; set; }

    public string Parent { get; set; }

    public Blueprint()
    {
        Components = new ComponentTable();

        Children = new List<string>();
        Parent = "";
    }

    public Blueprint(Blueprint _blueprint)
    {
        Children = new List<string>(_blueprint.Children);

        Parent = _blueprint.Parent;
    }
}


public class ComponentTable : List<IEntityComponent>
{
    private Dictionary<Type, IEntityComponent> Components { get; set; }

    #region Constructors

    public ComponentTable()
    {
        Components = new Dictionary<Type, IEntityComponent>();
    }

    #endregion

    #region Base Function Overrides

    public void Add(Type _type)
    {
        if (Components.ContainsKey(_type))
            return;

        InternalAdd(_type, (IEntityComponent)Activator.CreateInstance(_type));
    }
    public new void Add(IEntityComponent _component)
    {
        InternalAdd(_component.GetType(), _component);
    }
    public void Add<T>() where T : IEntityComponent
    {
        Add(typeof(T));
    }
    private void InternalAdd(Type _type, IEntityComponent _component)
    {
        if (Components.ContainsKey(_type))
            throw new InvalidOperationException("Component already contained");

        Components.Add(_type, _component);
        base.Add(_component);
    }

    public bool Remove(Type _type)
    {
        if (Components.ContainsKey(_type))
            return InternalRemove(_type, Components[_type]);
        return false;
    }
    public new bool Remove(IEntityComponent _component)
    {
        return InternalRemove(_component.GetType(), _component);
    }
    public bool Remove<T>() where T : IEntityComponent
    {
        return Remove(typeof(T));
    }
    private bool InternalRemove(Type _type, IEntityComponent _component)
    {
        if (!Components.ContainsKey(_type))
            return false;

        Components.Remove(_type);
        return base.Remove(_component);
    }

    public IEntityComponent Get(Type _type)
    {
        if (Contains(_type))
            return Components[_type];
        return null;
    }
    public T Get<T>() where T : IEntityComponent
    {
        return (T)Get(typeof(T));
    }

    public bool TryGetValue(Type _type, out IEntityComponent _component)
    {
        return Components.TryGetValue(_type, out _component);
    }
    public bool TryGetValue<T>(out IEntityComponent _component) where T : IEntityComponent
    {
        return TryGetValue(typeof(T), out _component);
    }

    public bool Contains(Type _type)
    {
        return Components.ContainsKey(_type);
    }
    public new bool Contains(IEntityComponent _component)
    {
        return Contains(_component.GetType());
    }
    public bool Contains<T>() where T : IEntityComponent
    {
        return Contains(typeof(T));
    }

    #endregion

}
公共密封类蓝图
{
公共组件表组件{get;private set;}
公共列表子项{get;set;}
公共字符串父项{get;set;}
公共蓝图()
{
Components=新的ComponentTable();
Children=新列表();
父项=”;
}
公共蓝图(蓝图)
{
Children=新列表(_blueprint.Children);
父项=_blueprint.Parent;
}
}
公共类组件表:列表
{
专用字典组件{get;set;}
#区域构造函数
公共组件表()
{
组件=新字典();
}
#端区
#区域基函数覆盖
公共无效添加(类型_类型)
{
if(组件。容器(_类型))
返回;
InternalAdd(_类型,(IEntityComponent)Activator.CreateInstance(_类型));
}
公共新空添加(IEntityComponent\u组件)
{
InternalAdd(_component.GetType(),_component);
}
public void Add(),其中T:IEntityComponent
{
添加(类型(T));
}
私有void InternalAdd(类型_Type,IEntityComponent _component)
{
if(组件。容器(_类型))
抛出新的InvalidOperationException(“已包含组件”);
组件。添加(_类型,_组件);
添加(_组件);
}
公共布尔删除(类型_类型)
{
if(组件。容器(_类型))
返回内部删除(_类型,组件[_类型]);
返回false;
}
公共新bool删除(IEntityComponent\u组件)
{
返回InternalRemove(_component.GetType(),_component);
}
public bool Remove(),其中T:IEntityComponent
{
返回移除(类型(T));
}
私有bool InternalRemove(Type _Type,IEntityComponent _component)
{
如果(!Components.ContainsKey(_类型))
返回false;
组件。移除(_型);
返回底座。移除(_组件);
}
public-IEntityComponent-Get(类型_-Type)
{
if(包含(_类型))
返回组件[_类型];
返回null;
}
public T Get(),其中T:IEntityComponent
{
return(T)Get(typeof(T));
}
public bool TryGetValue(类型_Type,out-IEntityComponent _component)
{
返回组件.TryGetValue(_类型,out组件);
}
公共bool TryGetValue(out-EntityComponent _component),其中T:EntityComponent
{
返回TryGetValue(类型(T),输出组件);
}
公共布尔包含(类型_类型)
{
返回组件。ContainsKey(_类型);
}
公共新bool包含(IEntityComponent\u组件)
{
返回包含(_component.GetType());
}
public bool Contains(),其中T:IEntityComponent
{
返回包含(类型(T));
}
#端区
}

我在Microsoft.Net上对此进行了测试,发现以下问题:

  • 将不会反序列化
    组件
    属性,除非该属性具有公共setter:

    public sealed class Blueprint 
    {
        public ComponentTable Components { get; set; }
    
    似乎没有任何类型的配置选项可以解决此问题。从中可以看到,如果setter不是公共的,则创建setter委托的方法返回
    null

    internal static GenericSetter CreateSetMethod(Type type, PropertyInfo propertyInfo)
    {
        MethodInfo setMethod = propertyInfo.GetSetMethod();
        if (setMethod == null)
            return null;
    
  • fastJSON似乎确实无法反序列化非泛型的
    List
    ——或任何其他非数组集合类的子类。内部有以下检查:

    if (pi.IsGenericType && pi.IsValueType == false && v is List<object>)
        oset = CreateGenericList((List<object>)v, pi.pt, pi.bt, globaltypes);
    
    然后将蓝图更改为:

    public sealed class Blueprint
    {
        public ComponentTable<IEntityComponent> Components { get; set; }
    
    现在可以在Microsoft.Net上序列化和反序列化集合,而不会损坏数据。但是

  • 我不确定unity中是否存在
    KeyedByTypeCollection
    。如果不存在,您可能需要对其进行移植。请参阅引用源和基类源。可以在此处找到一次尝试:

  • >P>作为替代方案,您可以考虑使用JSON.NET.jSON.NET支持通过.Services序列化多态性。但是,在Unity?/P>上是否可用? 这里有一些统一的端口。例如,这里也有各种各样的问题。所以,你可以进一步研究这个选项


    认真回答10/10。你比我预想的要详细得多,非常感谢。我甚至没有意识到KeyedByTypeCollection类的存在,我将尝试改变这一点,看看它如何与fastJSON一起工作。我假设你尝试过用fastJS序列化它
    public sealed class Blueprint
    {
        public ComponentTable<IEntityComponent> Components { get; set; }
    
    public class ComponentTable<TEntityComponent> : KeyedByTypeCollection<TEntityComponent> where TEntityComponent : IEntityComponent
    {
        public void Add(Type _type)
        {
            if (Contains(_type))
                return;
            Add((TEntityComponent)Activator.CreateInstance(_type));
        }
    
        public void Add<T>() where T : IEntityComponent, new()
        {
            Add(typeof(T));
        }
    }