Unity热更新方案C#Like(十九)-详解KissJSON:唯一可以在本热更新框架使用的JSON库

C#Like是Unity的热更方案,使用纯C#语言写出可以热更新的代码,就像可以在所有平台使用DLL(动态链接库)文件一样.遵从KISS设计原则,让用户轻松构建或升级成Unity的热更新项目.

简介

本篇主要介绍唯一可以在C#Like热更新框架使用的JSON库KissJSON,为C#Like度身定做的,后来也发布源码到GitHub,让所有的C#代码都可以免费使用.

这个世界上的JSON库何其多,KissJSON跟其他的JSON库比,有什么特别过人之处?

  • 完全兼容C#Like,可在热更脚本里使用
  • JSONData与内置类型无缝互转,直接当做内置类型使用,例如数值计算
  • JSON字符串与JSONData与类/结构体之间轻松转换

用法:

 1 可与JSONData之间直接互转的内置类型:
  • 内置类型: string sbyte ushort uint ulong byte short int long bool float double DateTime  
  • 可空内置类型: sbyte? ushort? uint? ulong? byte? short? int? long? bool? float? double? DateTime?
  • 枚举
  • List<内置类型>
  • Dictionary<string,内置类型>
2 JSONData与内置类型无缝互转,直接当做内置类型使用,例如数值计算:
  • 内置类型 ->JSONData
JSONData iData = 2;  
Console.WriteLine("JSONData iData = 2;  test iData = " + iData);//输出 2  
JSONData fData = 88.8f;  
Console.WriteLine("JSONData fData = 88.8f;  test fData = " + fData);//输出 88.8  
List<string> listValue = new List<string>();  
listValue.Add("test list str1");  
listValue.Add("test list str2");  
JSONData listData = listValue;  
Console.WriteLine("JSONData listData = listValue;  test listData = " + listData);//输出 ["test list str1","test list str2"]  
Dictionary<string, int> dictValue = new Dictionary<string, int>();  
dictValue.Add("key1", 11);  
dictValue.Add("key2", 22);  
JSONData dictData = dictValue;  
Console.WriteLine("JSONData dictData = dictValue;  test dictData = " + dictData);//输出 {"key1":11,"key2":22}  
  • JSONData -> 内置类型
int iValue = iData;  
Console.WriteLine("int iValue = iData;  test iValue = " + iValue);//输出 2  
float fValue = fData;  
Console.WriteLine("float fValue = fData;  test fValue = " + fValue);//输出 88.8  
List<string> listValue2 = listData;  
string strTemp = "";  
foreach (var str in listValue2)  
    strTemp += str + ",";  
Console.WriteLine("List<string> listValue2 = listData;  test listValue2 = " + strTemp);//输出 test list str1,test list str2,  
Dictionary<string, int> dictValue2 = dictData;  
strTemp = "";  
foreach (var item in dictValue2)  
    strTemp += "(" + item.Key + "=" + item.Value + ")";  
Console.WriteLine("Dictionary<string, int> dictValue2 = dictData;  test dictValue2 = " + strTemp);//输出 (key1=11)(key2=22)  
  • JSONData 与 内置类型 之间数值运算
JSONData exprData1 = 2;  
JSONData exprData2 = 3;  
JSONData exprData3 = exprData1 * exprData2;  
Console.WriteLine("test Math Expression;  exprData3 = exprData1 * exprData2; exprData3 = " + exprData3);//输出 6  
exprData3 = exprData1 << 5;  
Console.WriteLine("test Math Expression;  exprData3 = exprData1 << 5; exprData3 = " + exprData3);//输出 64  
exprData3 = exprData1 - exprData2;  
Console.WriteLine("test Math Expression;  exprData3 = exprData1 - exprData2; exprData3 = " + exprData3);//输出 -1  
exprData3 *= exprData2;//exprData3=-1;exprData2=3  
Console.WriteLine("test Math Expression;  exprData3 *= exprData2; exprData3 = " + exprData3);//输出 -3  
  
iData = 2;  
if (iData > 1)  
    Console.WriteLine("test Math Expression;  iData = 2, enter if (iData > 1)");//进入这里  
else  
    Console.WriteLine("test Math Expression;  iData = 2, not enter if (iData > 1)");  
3 JSON字符串与JSONData与类之间轻松转换:
  • JSON字符串 -> JSONData
string strJson = @"{  
 "str": "{test \"str",   
 "i": 11,   
 "j": 2.3,   
 "k": [  
   3,   
   null,   
   {  
     "m": true  
   }  
 ],   
 "l": {  
   "x": 1,   
   "y": "abc"  
 }  
";  
JSONData data = KissJson.ToJSONData(strJson);  
//accept JSONData by ["key"] and [index]  
Console.WriteLine("JSON string => JSONData; test data[\"str\"] = " + data["str"]);//输出 {test "str  
Console.WriteLine("JSON string => JSONData; test data[\"i\"] = " + data["i"]);//输出 11  
Console.WriteLine("JSON string => JSONData; test data[\"j\"] = " + data["j"]);//输出 2.3  
Console.WriteLine("JSON string => JSONData; test data[\"k\"] = " + data["k"]);//输出 [3,null,{"m":true}]  
Console.WriteLine("JSON string => JSONData; test data[\"l\"] = " + data["l"]);//输出 {"x":1,"y":"abc"}  
Console.WriteLine("JSON string => JSONData; test data[\"k\"][0] = " + data["k"][0]);//输出 3  
Console.WriteLine("JSON string => JSONData; test data[\"l\"][\"y\"] = " + data["l"]["y"]);//输出 abc  
Console.WriteLine("JSON string => JSONData; test data[\"k\"][2][\"m\"] = " + data["k"][2]["m"]);//输出 true 
  • JSONData -> JSON字符串
JSONData listData3 = JSONData.NewDictionary();  
listData3.Add("key1", 10);         //类似Dictionary的函数'Add(key,value)'的方式加数据  
listData3["key2"] = "test string"; //类似Dictionary/List索引'this[]'的方式加数据  
listData3["key3"] = JSONData.NewList(); //我们加一个List类型的JSONData  
if (listData3.ContainsKey("key3"))  //确保'key3'是否存在,如果你不确认的情况下  
    listData3["key3"].Add(1);       //插入一些数据到list里  
listData3["key3"].Insert(0,"string2"); //插入一些数据到list里, 我们这里不检查'key3'是否存在,因为我们已经确认它是存在的  
listData3["key4"] = JSONData.NewDictionary(); //我们加一个Dictionary类型的JSONData  
listData3["key4"]["x"] = 1;  
listData3["key4"]["y"] = 2;  
listData3["key4"]["z"] = 3;  
Debug.Log("test JSONData => JSON string; strJson = " + listData3.ToJson());//输出 {"key1":10,"key2":"test string","key3":["string2",1],"key4":{"x":1,"y":2,"z":3}} 
  • 与JSON字符串/JSONData互转相关的类/结构体
/// <summary>  
/// 测试 类 <=> JSON字符串  
/// </summary>  
public class TestJsonDataSub  
{  
    public int? id;//测试可空类型  
    public string name;  
    public Vector2 v2;//你可以添加其他类型,例如Color/Rect/Vector3/...  
    public List<string> info;  
    public Dictionary<string, int> maps;  
}  
//类被标为KissJsonDontSerialize的类会被JSON解析器忽略  
[KissJsonDontSerialize]  
public class TestJsonDataSub2  
{  
    public int id;  
}  
/// <summary>  
/// 测试 类 <=> JSON字符串  
/// </summary>  
public class TestJsonData  
{  
    [KissJsonDontSerialize]  
    public string str;//被标为KissJsonDontSerialize的属性会被JSON解析器忽略  
    public int i;  
    public DayOfWeek j;//测试枚举(非热更脚本)  
    public TestHotUpdateEnum z;//测试枚举(热更脚本)  
    public List<int?> k;  
    public Dictionary<string, TestJsonDataSub> datas;//测试Dictionary  
    public TestJsonDataSub data;//测试单个的类中类  
    public TestJsonDataSub2 data2;//这个会被JSON解析器忽略,因为TestJsonDataSub2这个类被标为KissJsonDontSerialize  
}  
/// <summary>  
/// 测试枚举  
/// </summary>  
public enum TestHotUpdateEnum  
{  
    Morning,  
    Afternoon,  
    Evening  
}    
/// <summary>  
/// 测试结构体  
/// </summary>  
public struct Vector2  
{  
    public float x;  
    public float y;  
    public override string ToString()  
    {  
        return $"({x:F2},{y:F2})";  
    }  
} 
  • JSON字符串 -> 类/结构体
strJson = "{\"str\":\"{test str\",\"i\":11,\"j\":1,\"z\":2,\"k\":[3,null,7],\"datas\":{\"aa\":{\"id\":1,\"name\":\"aaa\",\"v2\":{\"x\":1,\"y\":2},\"info\":[\"a\",\"xd\",\"dt\"],\"maps\":{\"x\":1,\"y\":2}},\"bb\":{\"id\":2,\"name\":\"bbb\",\"v2\":{\"x\":3,\"y\":4},\"info\":[\"x\",\"x3d\",\"ddt\"],\"maps\":{\"x\":2,\"y\":3}}},\"data\":{\"id\":3,\"name\":\"ccc\",\"v2\":{\"x\":3,\"y\":1},\"info\":[\"ya\",\"xyd\",\"drt\"],\"maps\":{\"x\":3,\"y\":4}}}";  
TestJsonData testJsonData = (TestJsonData)KissJson.ToObject(typeof(TestJsonData), strJson);//JSON 字符串 => 类  
测试 JSONData => 类  
//TestJsonData testJsonData = (TestJsonData)KissJson.ToObject(typeof(TestJsonData), KissJson.ToJSONData(strJson));//JSONData => 类  
Console.WriteLine(testJsonData.str);//输出 Null  
Console.WriteLine(testJsonData.i);//输出 11  
//"j":"Monday"和"j":"1"和"j":1都会识别为'DayOfWeek.Monday'  
//推荐使用"j":1,因为ToJson()会输出为"j":1  
Console.WriteLine(testJsonData.j);//输出 Monday  
Console.WriteLine((int)testJsonData.j);//输出 1  
Console.WriteLine(testJsonData.z);//输出 2  
foreach (var item in testJsonData.k)  
    Console.WriteLine(item);//输出 3/输出 null/输出 7  
foreach (var datas in testJsonData.datas)  
{  
    Console.WriteLine(datas.Key);//输出 aa/输出 bb  
    Console.WriteLine(datas.Value.v2);//输出 (1.0, 2.0)/输出 (3.0, 4.0)  
}  
  • 类/结构体 -> JSON字符串
strTemp = KissJson.ToJson(testJsonData);//类/结构体 => JSON字符串  
Console.WriteLine(strTemp);//输出 {"i":11,"j":1,"z":2,"k":[3,null,7],"datas":{"aa":{"id":1,"name":"aaa","v2":{"x":1,"y":2},"info":["a","xd","dt"],"maps":{"x":1,"y":2}},"bb":{"id":2,"name":"bbb","v2":{"x":3,"y":4},"info":["x","x3d","ddt"],"maps":{"x":2,"y":3}}},"data":{"id":3,"name":"ccc","v2":{"x":3,"y":1},"info":["ya","xyd","drt"],"maps":{"x":3,"y":4}}}
  • 类/结构体 -> JSONData
data = KissJson.ToJSONData(testJsonData);  
4 格式化JSON字符串:

    Console.WriteLine(data.ToJson(true));//格式化JSON字符串,更好的可读性  
    Console.WriteLine(data.ToJson());//不格式化JSON字符串,可读性差但JSON字符串很短,更适合传输  
  
格式化JSON字符串为:  
{  
    "i": 11,  
    "j": 1,  
    "z": 2,  
    "k": [  
        3,  
        null,  
        7  
    ],  
    "datas": {  
        "aa": {  
            "id": 1,  
            "name": "aaa",  
            "v2": {  
                "x": 1,  
                "y": 2  
            },  
            "info": [  
                "a",  
                "xd",  
                "dt"  
            ],  
            "maps": {  
                "x": 1,  
                "y": 2  
            }  
        },  
        "bb": {  
            "id": 2,  
            "name": "bbb",  
            "v2": {  
                "x": 3,  
                "y": 4  
            },  
            "info": [  
                "x",  
                "x3d",  
                "ddt"  
            ],  
            "maps": {  
                "x": 2,  
                "y": 3  
            }  
        }  
    },  
    "data": {  
        "id": 3,  
        "name": "ccc",  
        "v2": {  
            "x": 3,  
            "y": 1  
        },  
        "info": [  
            "ya",  
            "xyd",  
            "drt"  
        ],  
        "maps": {  
            "x": 3,  
            "y": 4  
        }  
    }  
}  
不格式化JSON字符串:  
{"i":11,"j":1,"z":2,"k":[3,null,7],"datas":{"aa":{"id":1,"name":"aaa","v2":{"x":1,"y":2},"info":["a","xd","dt"],"maps":{"x":1,"y":2}},"bb":{"id":2,"name":"bbb","v2":{"x":3,"y":4},"info":["x","x3d","ddt"],"maps":{"x":2,"y":3}}},"data":{"id":3,"name":"ccc","v2":{"x":3,"y":1},"info":["ya","xyd","drt"],"maps":{"x":3,"y":4}}}  
5 深复制JSONData:

JSONData clone = JSONData.DeepClone(data);//深复制JSONData对象, 'clone'和'data'是两个独立的对象.  
JSONData notClone = data;  //仅仅是复制,相当于'notClone'是'data'的别名,它们是同一个对象.  
data["i"] = 100;//修改'data'对象,不会影响到'clone'对象的数值.  
Console.WriteLine(clone.ToJson());  
Console.WriteLine(notClone.ToJson());  

 本系列文章导读:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C#Like

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值