| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- using System;
- using System.Reflection;
- using System.Collections.Generic;
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- namespace JCUnityLib
- {
- public class CustomJson
- {
- public Dictionary<Type, Func<object, JToken>> importerDict = new Dictionary<Type, Func<object, JToken>>();
- public Dictionary<Type, Func<JToken, object>> exporterDict = new Dictionary<Type, Func<JToken, object>>();
- public CustomJson()
- {
- //add importer
- importerDict.Add(typeof(short), (o) => JValue.FromObject(o));
- importerDict.Add(typeof(int), (o) => JValue.FromObject(o));
- importerDict.Add(typeof(long), (o) => JValue.FromObject(o));
- importerDict.Add(typeof(float), (o) => JValue.FromObject(o));
- importerDict.Add(typeof(double), (o) => JValue.FromObject(o));
- importerDict.Add(typeof(bool), (o) => JValue.FromObject(o));
- importerDict.Add(typeof(double[][]), (o) => JArray.FromObject(o));
- importerDict.Add(typeof(Nullable<bool>), (o) => JValue.FromObject(o));
- //add exporter
- exporterDict.Add(typeof(short), (jt) => jt.ToObject<short>());
- exporterDict.Add(typeof(int), (jt) => jt.ToObject<int>());
- exporterDict.Add(typeof(long), (jt) => jt.ToObject<long>());
- exporterDict.Add(typeof(float), (jt) => jt.ToObject<float>());
- exporterDict.Add(typeof(double), (jt) => jt.ToObject<double>());
- exporterDict.Add(typeof(bool), (jt) => jt.ToObject<bool>());
- exporterDict.Add(typeof(double[][]), (jt) => ((JArray)jt).ToObject<double[][]>());
- exporterDict.Add(typeof(Nullable<bool>), (jt) => jt.ToObject<Nullable<bool>>());
- }
- public void InitJsonClass<T>(Func<object, JToken> importer, Func<JToken, object> exporter)
- {
- Type type = typeof(T);
- importerDict.Add(type, importer);
- exporterDict.Add(type, exporter);
- }
- public void InitJsonClass<T>(Func<object> ctor, params string[] props)
- {
- Type type = typeof(T);
- exporterDict.Add(type, (jt) => {
- var o = ctor.Invoke();
- FetchFieldValues(o, jt, props);
- return o;
- });
- importerDict.Add(type, (o) => {
- JToken jt = new JObject();
- FetchJsonProperties(jt, o, props);
- return jt;
- });
- }
- public T Parse<T>(string text)
- {
- var jt = JToken.Parse(text);
- return (T)ParseByExporter(jt, typeof(T));
- }
- public string Stringify(object o)
- {
- return JsonConvert.SerializeObject(ToJTokenByImporter(o));
- }
- public void FetchJsonProperties(JToken target, object fromObject, params string[] propertyNames)
- {
- Type fromObjectType = fromObject.GetType();
- foreach (var propertyName in propertyNames)
- {
- FieldInfo targetField = fromObjectType.GetField(propertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
- if (targetField == null) {
- PropertyInfo propertyInfo = fromObjectType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
- if (propertyInfo == null) {
- throw new Exception($"获取PropertyInfo[{propertyName}]失败");
- } else {
- JToken propertyValue = ToJTokenByImporter(propertyInfo.GetValue(fromObject));
- target[propertyName] = propertyValue;
- }
- } else {
- JToken propertyValue = ToJTokenByImporter(targetField.GetValue(fromObject));
- target[propertyName] = propertyValue;
- }
- }
- }
- public JToken ToJTokenByImporter(object o)
- {
- if (o == null) return null;
- Type type = o.GetType();
- Func<object, JToken> importer = null;
- importerDict.TryGetValue(type, out importer);
- if (importer == null) {
- if (IsArray(type) && type.GetArrayRank() == 1) { //是一维数组才会触发
- Type elemType = type.GetElementType();
- importerDict.TryGetValue(elemType, out importer);
- if (importer == null) throw new Exception($"缺少Type<{elemType.Name}>的Importer");
- JArray ja = new JArray();
- Array arr = (Array) o;
- for (int i = 0; i < arr.Length; i++) ja.Add(importer.Invoke(arr.GetValue(i)));
- return ja;
- } else {
- throw new Exception($"缺少Type<{type.Name}>的Importer");
- }
- }
- return importer.Invoke(o);
- }
- public T ParseByExporter<T>(JToken jt)
- {
- return (T)ParseByExporter(jt, typeof(T));
- }
- public object ParseByExporter(JToken jt, Type type)
- {
- if (jt.Type == JTokenType.Null) return null;
- Func<JToken, object> exporter = null;
- exporterDict.TryGetValue(type, out exporter);
- if (exporter == null) {
- if (IsArray(type) && type.GetArrayRank() == 1) { //是一维数组才会触发
- Type elemType = type.GetElementType();
- exporterDict.TryGetValue(elemType, out exporter);
- if (exporter == null) throw new Exception($"缺少Type<{elemType.Name}>的Exporter");
- var ja = (JArray) jt;
- var arr = Array.CreateInstance(elemType, ja.Count);
- for (int i = 0; i < arr.Length; i++) arr.SetValue(exporter.Invoke(ja[i]), i);
- return arr;
- } else {
- throw new Exception($"缺少Type<{type.Name}>的Exporter");
- }
- }
- return exporter.Invoke(jt);
- }
- public void FetchFieldValues(object target, JToken fromJson, params string[] fieldNames) {
- Type targetType = target.GetType();
- foreach (var fieldName in fieldNames)
- {
- FieldInfo targetField = targetType.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
- if (targetField == null) {
- PropertyInfo propertyInfo = targetType.GetProperty(fieldName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
- if (propertyInfo == null) {
- throw new Exception($"获取PropertyInfo[{fieldName}]失败");
- } else {
- object fieldValue = ParseByExporter(fromJson[fieldName], propertyInfo.PropertyType);
- propertyInfo.SetValue(target, fieldValue);
- }
- } else {
- object fieldValue = ParseByExporter(fromJson[fieldName], targetField.FieldType);
- targetField.SetValue(target, fieldValue);
- }
- }
- }
- public bool IsArray(Type type)
- {
- return type.BaseType == typeof(Array);
- }
- }
- }
|