面向对象编程思想中,继承 确实是个好东西:提炼共性、逻辑复用、里氏转换。多少设计模式灵感都是以此为基点迸发,可见 继承 是多么重要,又是多么常见。
故而笔者觉得有必要带大家过一下 Json 在是怎么处理存在继承关系的 “对象们” 的。
写在前面:
一组继承了基类的差异化对象群体,可以声明基类类型的集合来统筹管理他们,这个就是里氏转换带来的便利。
Json 序列化和反序列化中如何原滋原味的保留这种 父亲可以代言儿子 的特性呢?
可以预见,使用public IList<Business> Businesses
来装载下图的Hotel
、Hostel
对象,
如果处理不好,反序列化后 Hostel
肯定会弄丢他的特殊服务!哦不~是弄丢了SpecialService
字段的数据。
![](https://img.haomeiwen.com/i3600713/b93f1e49a3174e86.png)
实现:
其实呢,Newtonsoft.Json 真的是为亲们的操碎了心,早早的就准备好了案例,笔者Keyin的这些个代码便是直接Ctrl+C、Ctrl+V过来的,真懒!
namespace zFrame.Demo
{
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public abstract class Business
{
public string Name { get; set; }
}
public class Hotel : Business
{
public int Stars { get; set; }
}
public class Hostel : Business
{
/// <summary>特殊服务</summary>
public string SpecialService { get; set; }
public int Stars { get; set; }
}
public class Stockholder
{
public string FullName { get; set; }
public IList<Business> Businesses { get; set; }
}
public class JsonSerializationDemo : MonoBehaviour
{
string path;
Stockholder stockholder;
private void Start()
{
path = FolderMaker.Creat(this, "json");
Stockholder stockholder = new Stockholder
{
FullName = "Steve Stockholder",
Businesses = new List<Business>
{
new Hotel
{
Name = "Hudson Hotel",
Stars = 4
},
new Hostel
{
SpecialService="电击疗法",
Name="特殊人类研究所",
Stars=1
}
}
};
string jsonTypeNameAll = JsonConvert.SerializeObject(stockholder, Formatting.Indented, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});
Debug.Log(jsonTypeNameAll);
using (StreamWriter writer=File.CreateText(path+"/Data.json") )
{
writer.WriteLine(jsonTypeNameAll);
}
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.T))
{
string json = File.ReadAllText(path + "/Data.json");
Debug.Log(json);
stockholder = JsonConvert.DeserializeObject<Stockholder>(json, new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Auto
});
}
}
}
}
-
为确保反系列化时类型正确,在序列化的时候必须使用创建一个序列化配置器,如下:
-
为了确保反序列化成功,在执行反序列化的时也需要创建配置器,如下:
不可或缺哦
- 上面的代码中有一个奇奇怪怪的类:FolderMaker ,笔者用它获取Demo脚本的同级目录,方便保存序列化的数据, 往后不管Demo怎么被移植,这个反序列的数据永远在同级目录下呢。
动画演示:
![](https://img.haomeiwen.com/i3600713/d3b3fae666920a90.gif)
Tips:
- 运行后脚本同级生成名称为 “Json” 的文件夹,刷新可见保存了的反序列化文件。
- 打开反序列化文件,可见 Json 数据都是包含了类型了的, 用 $type 键映射。
- 笔者修改了 Json 数据,按 T 反序列化,断点调试可见数据都正确的被抓取过来了。
扩展阅读:
TypeNameHandling setting
Unity3d 使用代码在脚本同级目录下创建文件夹 - FolderMaker
网友评论