"Assets.Logic.CompGroundType,Assembly-CSharp,Version=0.0.0.0,Culture=neutral,PublicKeyToken=null": { "$type": "Assets.Logic.CompGroundType,Assembly-CSharp","GroundType": 1,"EntityID": 1,"<GroundType>k__backingField": 1 }
“GroundType”是枚举,“EntityID”是int.
这是我想要的结果:
"Assets.Logic.CompGroundType" : { "$type": "Assets.Logic.CompGroundType","<GroundType>k__backingField": 1 }
如果可能的话,我还想删除“$type”字段,同时仍然正确地反序列化继承的类型(我不确定为什么它是必要的,因为该信息是从上面的一行重复,但如果我通过设置TypeNameHandling删除它.没有,我得到了子类型的反序列化错误.我也不确定最后一个字段(k__backingField)的用途.
如果有可能,我想进一步减少它,以:
"Assets.Logic.CompGroundType" : { "GroundType": 1,}
我知道可以在Json.Net中为每种类型手动定制序列化方案,但我有数百种类型,所以我想通过一些全局设置自动完成.
我尝试更改“FormatterassemblyStyle”,但没有“None”选项,只有“Simple”或“Full”,我已经使用“Simple”了.
在此先感谢您的帮助.
编辑:
重要的是要注意类型是字典中的键.这就是类型出现两次的原因(在第一个例子的第一行和第二行).
实现自定义SerializationBinder后,我能够减少“$type”字段的长度,但不能缩短Dictionary键字段的长度.现在我得到以下内容:
"componentDict": { "Assets.Logic.CompGroundType,PublicKeyToken=null": { "$type": "Assets.Logic.CompGroundType","<GroundType>k__backingField": 1 } }
编辑2:
我正在尝试序列化的代码是entity component system.我将尝试提供代码示例的详细示例.
所有组件(包括上面的CompGroundType)都继承自以下抽象类:
abstract class Component { public int EntityID { get; private set; } protected Component(int EntityID) { this.EntityID = EntityID; } }
我遇到的问题是在Entity类的componentDict的序列化中:
class Entity { readonly public int id; private Dictionary<Type,Component> componentDict = new Dictionary<Type,Component>(); [JsonConstructor] private Entity(Dictionary<Type,Component> componentDict,int id) { this.id = id; this.componentDict = componentDict; } }
componentDict包含附加到实体的所有组件.在每个条目< Type,Component>中,值的类型等于键.
我使用以下JsonSerializerSettings递归地进行序列化:
JsonSerializerSettings serializerSettings = new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore,ContractResolver = new MyContractResolver(),TypeNameHandling = TypeNameHandling.Auto,SerializationBinder = new TypesWithNoAssmeblyInfoBinder(),Formatting = Formatting.Indented }
MyContractResolver与this answer的形式相同.
TypesWithNoAssmeblyInfoBinder从编辑1进行更改:
private class TypesWithNoAssmeblyInfoBinder : ISerializationBinder { public Type BindToType(string assemblyName,string typeName) { return Type.GetType(typeName); } public void BindToName(Type serializedType,out string assemblyName,out string typeName) { assemblyName = null; typeName = serializedType.FullName; } }
序列化本身如下:
var jsonSerializer = JsonSerializer.Create(serializerSettings); using (FileStream zippedFile = new FileStream(Application.persistentDataPath + fileName,FileMode.Create)) { using (GZipStream archive = new GZipStream(zippedFile,CompressionLevel.Fastest)) { using (StreamWriter sw = new StreamWriter(archive)) { jsonSerializer.Serialize(sw,savedData); } } }
编辑4:
CompGroundType类(已完成组件的示例):
class CompGroundType : Component { public enum Type {Grass,Rock}; public Type GroundType { get; private set; } [JsonConstructor] private CompGroundType(Type groundType,int entityID) : base(entityID) { this.GroundType = groundType; } }
解决方法
public class KNownTypesBinder : ISerializationBinder { public IList<Type> KNownTypes { get; set; } public Type BindToType(string assemblyName,string typeName) { return KNownTypes.SingleOrDefault(t => t.Name == typeName); } public void BindToName(Type serializedType,out string typeName) { assemblyName = null; typeName = serializedType.Name; } } public class Car { public string Maker { get; set; } public string Model { get; set; } } KNownTypesBinder kNownTypesBinder = new KNownTypesBinder { KNownTypes = new List<Type> { typeof(Car) } }; Car car = new Car { Maker = "Ford",Model = "Explorer" }; string json = JsonConvert.SerializeObject(car,Formatting.Indented,new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects,SerializationBinder = kNownTypesBinder }); Console.WriteLine(json); // { // "$type": "Car",// "Maker": "Ford",// "Model": "Explorer" // } object newValue = JsonConvert.DeserializeObject(json,SerializationBinder = kNownTypesBinder }); Console.WriteLine(newValue.GetType().Name); // Car
它只需要根据您的特定需求进行调整.
然后第二部分是字典键,它来自被序列化的Type对象.
我认为你可以在creating a custom JsonConverter之前自定义它,但事实证明字典键有“特殊”处理,这意味着更复杂的解决方法.我没有一个更复杂的解决方法的例子抱歉.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。