面向?qū)ο缶幊趟枷胫校?strong>繼承 確實是個好東西:提煉共性年缎、邏輯復(fù)用、里氏轉(zhuǎn)換铃慷。多少設(shè)計模式靈感都是以此為基點(diǎn)迸發(fā)单芜,可見 繼承 是多么重要,又是多么常見犁柜。
故而筆者覺得有必要帶大家過一下 Json 在是怎么處理存在繼承關(guān)系的 “對象們” 的洲鸠。
寫在前面:
一組繼承了基類的差異化對象群體,可以聲明基類類型的集合來統(tǒng)籌管理他們,這個就是里氏轉(zhuǎn)換帶來的便利扒腕。
Json 序列化和反序列化中如何原滋原味的保留這種 父親可以代言兒子 的特性呢绢淀?
可以預(yù)見,使用public IList<Business> Businesses
來裝載下圖的Hotel
瘾腰、Hostel
對象皆的,
如果處理不好,反序列化后 Hostel
肯定會弄丟他的特殊服務(wù)蹋盆!哦不~是弄丟了SpecialService
字段的數(shù)據(jù)祭务。
實現(xiàn):
其實呢,Newtonsoft.Json 真的是為親們的操碎了心,早早的就準(zhǔn)備好了案例怪嫌,筆者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>特殊服務(wù)</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
});
}
}
}
}
-
為確保反系列化時類型正確拌倍,在序列化的時候必須使用創(chuàng)建一個序列化配置器,如下:
-
為了確保反序列化成功噪径,在執(zhí)行反序列化的時也需要創(chuàng)建配置器柱恤,如下:
不可或缺哦 - 上面的代碼中有一個奇奇怪怪的類:FolderMaker ,筆者用它獲取Demo腳本的同級目錄找爱,方便保存序列化的數(shù)據(jù), 往后不管Demo怎么被移植梗顺,這個反序列的數(shù)據(jù)永遠(yuǎn)在同級目錄下呢。
動畫演示:
demo
Tips:
- 運(yùn)行后腳本同級生成名稱為 “Json” 的文件夾车摄,刷新可見保存了的反序列化文件寺谤。
- 打開反序列化文件,可見 Json 數(shù)據(jù)都是包含了類型了的吮播, 用 $type 鍵映射变屁。
- 筆者修改了 Json 數(shù)據(jù),按 T 反序列化意狠,斷點(diǎn)調(diào)試可見數(shù)據(jù)都正確的被抓取過來了粟关。
擴(kuò)展閱讀:
TypeNameHandling setting
Unity3d 使用代碼在腳本同級目錄下創(chuàng)建文件夾 - FolderMaker