当前位置: 首页 > news >正文

三五互联做网站怎么样无锡网站建设和

三五互联做网站怎么样,无锡网站建设和,泰安营销型网站建设,校园网站建立文档 Json序列化 脚本序列化 问题 Unity序列化数组时,只能存储基类内容,子类内容缺少。 Unity版本 2019.4.40 原因:Unity序列化不支持多态 测试类 将testarray类序列化时,多态列表personlist只转换了基类数据,子类…

文档

Json序列化
脚本序列化

问题

Unity序列化数组时,只能存储基类内容,子类内容缺少。
Unity版本 2019.4.40
原因:Unity序列化不支持多态

测试类
将testarray类序列化时,多态列表personlist只转换了基类数据,子类数据没有转换

    public class Person{public string name = "1";}[System.Serializable]public class Student : Person{public string grade = "2";}[System.Serializable]public class TestArray{public List<Person> personList;}

测试

private void Start()
{TestArray testArray = new TestArray();testArray.personList = new List<Person>() { new Person(), new Student() };var content = JsonUtility.ToJson(testArray);Debug.Log(content);
}

输出结果
student实例的内容grade没有转换

打印:{"personList":[{"name":"1"},{"name":"1"}]}

解决方法

将多态数组拆分为有具体类型的多个数组
相同类型的元素存储到相同类型的数组中,避免多态
优点:思路简单,效率高
缺点:没有了多态的特性

[System.Serializable]
public class Grade3
{public List<Student> students;public List<Person> persons;
}

解决方法1

JsonUtility可以将多态数组的元素完整转换
利用该特点,将多态数组的子元素转存为类型子元素对应的Json字符串
优点:思路简单
缺点:不同类型的多态数组都需要实现转换逻辑,效率低,频繁使用JsonUtility方法GC多
适用于:数据量较少,子类数量不固定

测试类
解释:自定义类实现ISerializationCallbackReceiver接口,
序列化之前,将多态数组中的元素保存为类型和数据字符串
反序列化之后,遍历类型和数据字符串,利用反射和json反序列化,将数据还原到到多态数组中

    [System.Serializable]public class Grade : ISerializationCallbackReceiver{[NonSerialized]public Person[] personList;[SerializeField]private string[] types;[SerializeField]private string[] datas;public void OnBeforeSerialize()//序列化之前{if (personList != null && personList.Length > 0){var length = personList.Length;types = new string[length];datas = new string[length];for (int i = 0; i < length; i++){types[i] = personList[i].GetType().FullName;//存储子元素类型datas[i] = JsonUtility.ToJson(personList[i]);//存储子元素转换的字符串}}}public void OnAfterDeserialize(){if (types != null && datas != null){var length = types.Length;personList = new Person[length];Dictionary<string, Type> typeDic = new Dictionary<string, Type>();//缓存类型避免频繁获取for (int i = 0; i < length; i++){if (!typeDic.ContainsKey(types[i]))typeDic.Add(types[i], Type.GetType(types[i]));var type = typeDic[types[i]];if (type != null && typeof(Person).IsAssignableFrom(type)){Person person = (Person)Activator.CreateInstance(type);//反射创建实例元素JsonUtility.FromJsonOverwrite(datas[i], person);//反序列化数据存放到实例中personList[i] = person;}}}}public void Print()//打印数组元素{for (int i = 0; i < personList.Length; i++){Debug.Log(personList[i]);}}}

测试

private void Start()
{var grade = new Grade();grade.personList = new Person[2] { new Person(), new Student() };var info = JsonUtility.ToJson(grade);Debug.Log(info);
}

输出结果
student实例的内容grade转换

打印:
{
"types":["Test.Person","Test.Student"],
"datas":["{\"name\":\"1\"}","{\"name\":\"1\",\"grade\":\"2\"}"]
}

解决方法2

优点:序列化速度比方法1快,保留多态特性
缺点:子类数量一旦过多,需要编写更多脚本
适用于子类数目较少的,不需要元素的顺序

测试类
解释:序列化时,将多态数组中的数据存放到对应类型的数组中,减少Json方法的调用
反序列化时,将对应数组中的数据存放到多态数组中

    public class Grade2 : ISerializationCallbackReceiver{[NonSerialized]public List<Person> runtimes;//不需要序列化多态数组[SerializeField] Student[] students;[SerializeField] Person[] persons;public void OnBeforeSerialize(){this.students = null;this.persons = null;if (runtimes != null && runtimes.Count > 0){var length = runtimes.Count;int[] indexArray = new int[length];//索引数组int arrayLength = 0;Type targetType = typeof(Student);for (int i = 0; i < length; i++){if (runtimes[i].GetType() == targetType){arrayLength++;indexArray[i] = i;//存放当前Type对应元素的索引}}if (arrayLength > 0){this.students = new Student[arrayLength];//直接设置长度for (int i = 0; i < arrayLength; i++)this.students[i] = runtimes[indexArray[i]] as Student;}arrayLength = 0;targetType = typeof(Person);for (int i = 0; i < length; i++){Type type = runtimes[i].GetType();if (type == targetType){arrayLength++;indexArray[i] = i;}}if (arrayLength > 0){this.persons = new Person[arrayLength];for (int i = 0; i < arrayLength; i++)this.persons[i] = runtimes[indexArray[i]];}}}public void OnAfterDeserialize(){int length = 0;if (students != null)length += students.Length;if (persons != null)length += persons.Length;runtimes = new List<Person>(length);//直接设置列表容量if (students != null)//填充runtimes.AddRange(students);if (persons != null)runtimes.AddRange(persons);}public void Print(){for (int i = 0; i < runtimes.Count; i++){Debug.Log(runtimes[i]);}}}

测试

var grade2 = new Grade2();
grade2.runtimes = new List<Person> { new Person(), new Student() };
var info2 = JsonUtility.ToJson(grade2);
Debug.Log(info2);

输出结果

打印:{"students":[{"name":"1","grade":"2"}],"persons":[{"name":"1"}]}

解决方法3

使用高版本Unity的[SerializeReference]特性
优点:不需要编写多余内容,使用简单,效率比方法1高
缺点:序列化效率差,存储文件大,只支持高版本

测试类

    [System.Serializable]public class Grade4{[SerializeReference]//添加特性public List<Person> runtimes;}

测试

Grade4 grade4 = new Grade4();
grade4.runtimes = new List<Person> { new Person(), new Student() };
var info3 = JsonUtility.ToJson(grade);
Debug.Log(info3);

输出结果

{
"runtimes":[{"rid":1000},{"rid":1001}],
"references":{"version":2,"RefIds":[{"rid":1000,"type":{"class":"Person","ns":"Test","asm":"Assembly-CSharp"},"data":{"name":"1"}},{"rid":1001,"type":{"class":"Student","ns":"Test","asm":"Assembly-CSharp"},"data":{"name":"1","grade":"2"}}]}}

解决方法4

使用Newtonsoft.Json第三方包
优点:功能强大,支持多态数组,使用简单
缺点:第三方导入,效率不高

测试

TestArray testArray5 = new TestArray();
testArray5.personList = new List<Person>() { new Person(), new Student() };JsonSerializerSettings settings = new JsonSerializerSettings();//序列化设置
settings.NullValueHandling = NullValueHandling.Ignore;//空值不保存
settings.TypeNameHandling = TypeNameHandling.Auto;//类型名称自动处理
settings.Formatting = Formatting.Indented;//格式化json文档
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;//忽略循环引用
var content5 = JsonConvert.SerializeObject(testArray, settings);
Debug.Log(content5);

输出结果

打印
{"personList": [{"name": "1"},{"$type": "Test.Student, Assembly-CSharp","grade": "2","name": "1"}]
}
http://www.yayakq.cn/news/108293/

相关文章:

  • 盐城微信公众平台网站制作win7 iis部署网站
  • h5制作工具网站网站源码模板
  • 四川省城镇建设二次供水网站南京尔顺科技发展有限公司表扬信息wordpress制作官方网站
  • 旅游网站后台模板百度网页版首页
  • 摄影网站建设目的wordpress外贸主题购买
  • 建站公司最新排名松原手机网站开发公司
  • 网站抬头怎么做佳易网页王
  • 杭州网站建设哪家公司好福州网站建设方案优化
  • 网站数据库一般多大太原网站建设口碑推荐
  • 东莞建网站公司动长沙网站建设优化
  • 泰安 网站建设公司wordpress调用访问次数
  • 自己做视频网站收益怎么来如何建设网站内容
  • 网站搜索排名优化价格四川做网站的
  • 自媒体横行还有做网站wordpress只让文章标题
  • 广州网站推广解决方案民政网站建设情况汇报
  • 建设自己的网站有什么ppt制作手机版
  • 收录网站的二级域名网站seo标题优化技巧
  • 寒亭营销型网站建设中区网站建设
  • php网站建设到护卫神wordpress建网店
  • 网站如何建立品牌形象wordpress 产品属性tag
  • 佛山企业网站设计公司app界面设计的软件
  • 网站嵌入js网上免费申请营业执照
  • html5国外网站模板html源码下载泉州中企网站做的好吗
  • 营口手机网站建设最新新闻消息
  • 深圳网站开发服务创新驱动发展战略意义
  • 招聘网站简历数据分析怎么做网站建设预计资金投入
  • 安达市建设局网站厦门专业建站系统制作公司
  • 西宁网站建设君博首选安阳网站制作
  • 做推广效果哪个网站好有偿做设计的网站
  • 校园招聘哪个网站做的好聊城专业做网站