简介
自定义思路
(一)问题
结合我在使用litjson过程中遇到的问题,主要针对四个常见问题进行自定义:
(二)解决方案
针对上述四个问题的解决方案如下:
方案1-4分别对应问题1-4,其中方案1涉及自定义特性[jsonassignable],方案2涉及自定义特性[jsonignore],方案3涉及自定义特性[jsoninclude],方案4涉及自定义特性[exportertarget]。
(三)特性
(四)其它自定义
测试代码(c#)
公共测试脚本test.cs
interface iperson
{
string mname { get; set; }
int mage { get; set; }
}
class persond : iperson
{
public string mname { get => name; set => name = value; }
public int mage { get => age; set => age = value; }
public string msex { get => sex; set => sex = value; }
string name;
int age;
string sex;
public override string tostring()
{
return $"[mname:{mname}, mage:{mage}, msex:{msex}]";
}
}
abstract class house
{
public string mname;
public float msize;
}
(1)测试jsonassignable特性:公共接口类型字段
using litjson.extensions;
using unityeditor;
using unityengine;
using litjson;
namespace jatest
{
class ja_test1
{
[menuitem("litjsontest/jsonassignable test/run the test1")]
static void test()
{
debug.log(new string('*', 80));
debug.log("<b><color=green>【测试jsonassignable特性:公共接口类型字段】</color></b>");
persond person = new persond
{
mname = "mike",
mage = 18,
msex = "male"
};
jahousea housea = new jahousea()
{
mname = "housea",
msize = 100,
person = person
};
string jsonstr = jsonmapper.tojson(housea);
debug.log(jsonstr);
jahousea housea1 = jsonmapper.toobject<jahousea>(jsonstr);
debug.log(housea1);
debug.log(new string('*', 80));
}
}
class jahousea : house
{
[jsonassignable] public iperson person;
public override string tostring()
{
return $"[mname:{mname}, msize:{msize}, person:{person}]";
}
}
}
(2)测试jsonassignable特性:公共抽象类类型字段
using litjson.extensions;
using unityeditor;
using unityengine;
using litjson;
namespace jatest
{
class ja_test2
{
[menuitem("litjsontest/jsonassignable test/run the test2")]
static void test()
{
debug.log(new string('*', 80));
debug.log("<b><color=green>【测试jsonassignable特性:公共抽象类类型字段】</color></b>");
jahouseb houseb = new jahouseb()
{
mname = "housea",
msize = 100
};
japersona person = new japersona
{
mname = "mike",
mage = 18,
house = houseb
};
string jsonstr = jsonmapper.tojson(person);
debug.log(jsonstr);
japersona persona = jsonmapper.toobject<japersona>(jsonstr);
debug.log(persona);
debug.log(new string('*', 80));
}
}
class jahouseb : house
{
public override string tostring()
{
return $"[mname:{mname}, msize:{msize}]";
}
}
class japersona : iperson
{
public string mname { get; set; }
public int mage { get; set; }
[jsonassignable] public house house;
public override string tostring()
{
return $"[mname:{mname}, mage:{mage}, house:{house}]";
}
}
}
(3)测试jsonignore特性:忽略公共字段
using unityeditor;
using unityengine;
using litjson;
using litjson.extensions;
namespace jiatest
{
class jig_test1
{
[menuitem("litjsontest/jsonignore test/run the test1")]
static void test()
{
debug.log(new string('*', 80));
debug.log("<b><color=green>【测试jsonignore特性:忽略公共字段】</color></b>");
jiaperson person = new jiaperson
{
mname = "mike",
mage = 18
};
jiahousea housea = new jiahousea()
{
mname = "housea",
msize = 100,
person = person
};
string jsonstr = jsonmapper.tojson(housea);
debug.log(jsonstr);
jiahousea housea1 = jsonmapper.toobject<jiahousea>(jsonstr);
debug.log(housea1);
debug.log(new string('*', 80));
}
}
class jiaperson : iperson
{
public string mname { get; set; }
public int mage { get; set; }
}
class jiahousea : house
{
[jsonignore] public jiaperson person;
public jiahousea() { }
public jiahousea(jiaperson person) { this.person = person; }
public override string tostring()
{
return $"[mname:{mname}, msize:{msize}, person:{person}]";
}
}
}
(4)测试jsoninclude特性:私有自定义类型字段
using litjson.extensions;
using unityengine;
using unityeditor;
using litjson;
namespace jitest
{
class ji_test1
{
[menuitem("litjsontest/jsoninclude test/run the test1")]
static void test()
{
debug.log(new string('*', 80));
debug.log("<b><color=green>【测试jsoninclude特性:私有自定义类型字段】</color></b>");
persond person = new persond
{
mname = "mike",
mage = 18,
msex = "male"
};
jihousea housea = new jihousea(person)
{
mname = "housea",
msize = 100
};
string jsonstr = jsonmapper.tojson(housea);
debug.log(jsonstr);
jihousea housea1 = jsonmapper.toobject<jihousea>(jsonstr);
debug.log(housea1);
debug.log(new string('*', 80));
}
}
class jihousea : house
{
[jsoninclude] private persond person;
// 必要条件:当有多个构造函数时应主动声明公共无参构造函数
public jihousea() { }
public jihousea(persond person) { this.person = person; }
public override string tostring()
{
return $"[mname:{mname}, msize:{msize}, person:{person}]";
}
}
}
(5)测试jsoninclude特性:私有自定义类型数组、列表和字典字段序列化和反序列化测试
using litjson.extensions;
using system.collections.generic;
using system.text;
using unityengine;
using unityeditor;
using litjson;
namespace jitest
{
class ji_test2
{
[menuitem("litjsontest/jsoninclude test/run the test2")]
static void test()
{
debug.log(new string('*', 80));
debug.log("<b><color=green>【测试jsoninclude特性:私有自定义类型数组、列表和字典字段序列化和反序列化测试】</color></b>");
persond persond = new persond()
{
mname = "mike",
mage = 20,
msex = "male"
};
persond persond2 = new persond()
{
mname = "lucy",
mage = 26,
msex = "female"
};
persond persond3 = new persond()
{
mname = "jack",
mage = 8,
msex = "male"
};
housef housef = new housef()
{
mname = "housef",
msize = 100
};
housef[0] = persond;
housef[1] = persond2;
housef[2] = persond3;
housef.addtolist(persond);
housef.addtolist(persond2);
housef.addtolist(persond3);
housef.addtodict(persond.mname, persond);
housef.addtodict(persond2.mname, persond2);
housef.addtodict(persond3.mname, persond3);
string jsonstr = jsonmapper.tojson(housef);
debug.log(jsonstr);
housef housef1 = jsonmapper.toobject<housef>(jsonstr);
debug.log(housef1);
debug.log(new string('*', 80));
}
}
class housef : house
{
[jsoninclude] private persond[] persons; // 用于测试私有自定义类型数组
[jsoninclude] private list<persond> personlist; // 用于测试私有自定义类型列表
[jsoninclude] private dictionary<string, persond> persondict; // 用于测试私有自定义类型字典
private int index;
public housef()
{
persons = new persond[3];
personlist = new list<persond>();
persondict = new dictionary<string, persond>();
index = 0;
}
public void addtolist(persond person)
{
personlist.add(person);
}
public void addtodict(string name, persond person)
{
persondict[name] = person;
}
public persond this[int index]
{
get
{
if (index >= 0 && index <= this.index) return persons[index];
return null;
}
set { if (index >= 0 && index < 3) persons[index] = value; }
}
public override string tostring()
{
stringbuilder stringbuilder = new stringbuilder($"[mname:{mname}, msize:{msize}, ");
stringbuilder.append("array:{");
for (int i = 0; i < persons.length; i++)
{
stringbuilder.append(persons[i] + ",");
}
stringbuilder.append("}, list:{");
for (int i = 0; i < personlist.count; i++)
{
stringbuilder.append(personlist[i] + ",");
}
stringbuilder.append("}, dict:{");
foreach (string key in persondict.keys)
{
stringbuilder.append(persondict[key] + ",");
}
stringbuilder.append("}]");
return stringbuilder.tostring();
}
}
}
(6)测试exportertarget特性:相同的自定义类型公共字段在不同的类中序列化规则不同
using unityeditor;
using unityengine;
using litjson;
using litjson.extensions;
namespace ettest
{
class et_test1
{
[menuitem("litjsontest/exportertarget test/run the test1")]
static void test()
{
debug.log(new string('*', 80));
debug.log("<b><color=green>【测试exportertarget特性:相同的自定义类型公共字段在不同的类中序列化规则不同】</color></b>");
etpersona person = new etpersona
{
mname = "mike",
mage = 18
};
ethousea housea = new ethousea()
{
mname = "housea",
msize = 100,
person = person
};
ethouseb houseb = new ethouseb()
{
mname = "houseb",
msize = 50,
person = person
};
string jsonstr = jsonmapper.tojson(housea);
debug.log(jsonstr);
ethousea housea1 = jsonmapper.toobject<ethousea>(jsonstr);
debug.log(housea1);
debug.log(new string('-', 80));
jsonstr = jsonmapper.tojson(houseb);
debug.log(jsonstr);
ethouseb houseb1 = jsonmapper.toobject<ethouseb>(jsonstr);
debug.log(houseb1);
debug.log(new string('*', 80));
}
}
class etpersona : iperson
{
public string mname { get; set; }
public int mage { get; set; }
public override string tostring()
{
return $"[mname:{mname}, mage:{mage}]";
}
}
[exportertarget(typeof(ethousea))]
class ethousea : house
{
public etpersona person;
static ethousea()
{
jsonmapper.registerexporter<etpersona, ethousea>((d, writer) =>
{
writer.writeobjectstart();
writer.writeproperty("etpersona", "ethousea_etpersona");
writer.writeobjectend();
});
}
public override string tostring()
{
return $"[mname:{mname}, msize:{msize}, person:{person}]";
}
}
[exportertarget(typeof(ethouseb))]
class ethouseb : house
{
public etpersona person;
static ethouseb()
{
jsonmapper.registerexporter<etpersona, ethouseb>((d, writer) =>
{
writer.writeobjectstart();
writer.writeproperty("etpersona", "ethouseb_etpersona");
writer.writeobjectend();
});
}
public override string tostring()
{
return $"[mname:{mname}, msize:{msize}, person:{person}]";
}
}
}
(7)json4unity:type类型变量的序列化和反序列化
using unityeditor;
using unityengine;
using litjson;
using system;
namespace jutest
{
class ju_test1
{
[menuitem("litjsontest/json4unity test/run the test1")]
static void test()
{
debug.log(new string('*', 80));
debug.log("<b><color=green>【json4unity:type类型变量的序列化和反序列化】</color></b>");
juhousea housea = new juhousea
{
mname = "housea",
msize = 100,
type = typeof(persond)
};
string jsonstr = jsonmapper.tojson(housea);
debug.log(jsonstr);
housea = jsonmapper.toobject<juhousea>(jsonstr);
debug.log(housea);
debug.log(new string('*', 80));
}
class juhousea : house
{
public type type;
public override string tostring()
{
return $"[mname:{mname}, msize:{msize}, type:{type}]";
}
}
}
}
(8)json4unity:unity常见数据结构vector2,vector3,vector4,rect,quaternion,color,
bounds的序列化和反序列化
using unityeditor;
using unityengine;
using litjson;
namespace jutest
{
class ju_test2
{
[menuitem("litjsontest/json4unity test/run the test2")]
static void test()
{
debug.log(new string('*', 80));
debug.log("<b><color=green>【json4unity:unity常见数据结构vector2,vector3,vector4,rect,quaternion,color,bounds的序列化和反序列化】</color></b>");
judata data = new judata
{
mvec2 = new vector2(2, 3),
mvec3 = new vector3(2, 3, 4),
mvec4 = new vector4(2, 3, 4, 5),
mrect = new rect(2, 3, 4, 5),
mquat = new quaternion(2, 3, 4, 5),
mcolor = new color(3, 2, 4, 5)
};
data.mbounds = new bounds(data.mvec3, data.mvec3);
string jsonstr = jsonmapper.tojson(data);
debug.log(jsonstr);
data = jsonmapper.toobject<judata>(jsonstr);
debug.log(data);
debug.log(new string('*', 80));
}
class judata
{
public vector2 mvec2;
public vector3 mvec3;
public vector4 mvec4;
public rect mrect;
public quaternion mquat;
public color mcolor;
public bounds mbounds;
public override string tostring()
{
return $"[vector2:{mvec2},vector3:{mvec3},vector4:{mvec4},rect:{mrect},quaternion:{mquat},color:{mcolor},bounds:{mbounds}]";
}
}
}
}
(9)相同的自定义类型公共字段在不同的类中反序列化规则不同
using unityeditor;
using unityengine;
using litjson;
namespace othertest
{
class ot_test1
{
[menuitem("litjsontest/other test/run the test1")]
static void test()
{
debug.log(new string('*', 80));
debug.log("<b><color=green>【相同的自定义类型公共字段在不同的类中反序列化规则不同】</color></b>");
otpersona person = new otpersona
{
mname = "mike",
mage = 18
};
othousea housea = new othousea()
{
mname = "housea",
msize = 100,
person = person
};
othouseb houseb = new othouseb()
{
mname = "houseb",
msize = 50,
person = person
};
string jsonstr = jsonmapper.tojson(housea);
debug.log(jsonstr);
othousea housea1 = jsonmapper.toobject<othousea>(jsonstr);
debug.log(housea1);
debug.log(new string('-', 80));
jsonstr = jsonmapper.tojson(houseb);
debug.log(jsonstr);
othouseb houseb1 = jsonmapper.toobject<othouseb>(jsonstr);
debug.log(houseb1);
debug.log(new string('*', 80));
}
}
class otpersona : iperson
{
public string mname { get; set; }
public int mage { get; set; }
public override string tostring()
{
return $"[mname:{mname}, mage:{mage}]";
}
}
class othousea : house
{
public otpersona person;
static othousea()
{
jsonmapper.registerimporterwithreader<otpersona, othousea>(reader =>
{
readerdata[] readerdatas = new readerdata[2];
for (int i = 0; i < reader.count; i++)
{
readerdatas[i] = reader.getdata();
}
return new otpersona
{
mname = (string)readerdatas[0].propertyvalue,
mage = (int)readerdatas[1].propertyvalue
};
});
}
public override string tostring()
{
return $"[mname:{mname}, msize:{msize}, person:{person}]";
}
}
class othouseb : house
{
public otpersona person;
static othouseb()
{
jsonmapper.registerimporterwithreader<otpersona, othouseb>(reader =>
{
readerdata[] readerdatas = new readerdata[2];
for (int i = 0; i < reader.count; i++)
{
readerdatas[i] = reader.getdata();
}
return new otpersona
{
mname = (string)readerdatas[0].propertyvalue,
mage = (int)readerdatas[1].propertyvalue
};
});
}
public override string tostring()
{
return $"[mname:{mname}, msize:{msize}, person:{person}]";
}
}
}
(10)对自定义类型公共字段自定义反序列化规则
using unityeditor;
using unityengine;
using litjson;
namespace othertest
{
class ot_test2
{
[menuitem("litjsontest/other test/run the test2")]
static void test()
{
debug.log(new string('*', 80));
debug.log("<b><color=green>【对自定义类型公共字段自定义反序列化规则】</color></b>");
otpersona person = new otpersona
{
mname = "mike",
mage = 18
};
othousec housec = new othousec
{
mname = "housec",
msize = 100,
person = person
};
string jsonstr = jsonmapper.tojson(housec);
debug.log(jsonstr);
othousec housec1 = jsonmapper.toobject<othousec>(jsonstr);
debug.log(housec1);
}
}
class othousec : house
{
public otpersona person;
static othousec()
{
jsonmapper.registerimporterwithreader(reader =>
{
readerdata[] readerdatas = new readerdata[2];
for (int i = 0; i < reader.count; i++)
{
readerdatas[i] = reader.getdata();
}
return new otpersona
{
mname = (string)readerdatas[0].propertyvalue,
mage = (int)readerdatas[1].propertyvalue
};
});
}
public override string tostring()
{
return $"[mname:{mname}, msize:{msize}, person:{person}]";
}
}
}
总结
对自定义内容进行了十项单元测试,且测试均通过,但未对自定义内容之间的组合使用进行联调测试(确实没啥时间),有热心网友请帮忙测试一下吧。
本文基于litjson进行自定义,扩展了以下功能:
1.对c#的type类型,以及接口类型或抽象类类型的字段或属性进行序列化和反序列化;
2.标记指定公有字段或属性不进行序列化和反序列化;
3.标记指定非公有字段或属性进行序列化和反序列化;
4.根据所在类不同,自定义同类型字段或属性的序列化或反序列化的局部规则;
5.对unity3d中常见数据结构的序列化和反序列化进行扩展。
资源下载
使用声明:litjson为开源插件,但请保护原作者基本权益以及尊重原作者的创作成果,合理合法进行使用,从本文直接或间接下载则默认同意并悉知该声明。
免责声明:由于本文内容未经过正规和严格的测试,可能存在错误,因此造成的损失均由使用者自行承担,对本文内容复制、下载、参考等引用行为即默认悉知并同意该声明。
如果这篇文章对你有帮助,请给作者点个赞吧!
发表评论