using System; using System.Reflection; using System.Collections.Generic; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace SmartBowSDK { public class CustomJson_SDK { public Dictionary> importerDict = new Dictionary>(); public Dictionary> exporterDict = new Dictionary>(); public CustomJson_SDK() { //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), (o) => JValue.FromObject(o)); //add exporter exporterDict.Add(typeof(short), (jt) => jt.ToObject()); exporterDict.Add(typeof(int), (jt) => jt.ToObject()); exporterDict.Add(typeof(long), (jt) => jt.ToObject()); exporterDict.Add(typeof(float), (jt) => jt.ToObject()); exporterDict.Add(typeof(double), (jt) => jt.ToObject()); exporterDict.Add(typeof(bool), (jt) => jt.ToObject()); exporterDict.Add(typeof(double[][]), (jt) => ((JArray)jt).ToObject()); exporterDict.Add(typeof(Nullable), (jt) => jt.ToObject>()); } public void InitJsonClass(Func importer, Func exporter) { Type type = typeof(T); importerDict.Add(type, importer); exporterDict.Add(type, exporter); } public void InitJsonClass(Func 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(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 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(JToken jt) { return (T)ParseByExporter(jt, typeof(T)); } public object ParseByExporter(JToken jt, Type type) { if (jt.Type == JTokenType.Null) return null; Func 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); } } }