CustomJson_SDK.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. using System;
  2. using System.Reflection;
  3. using System.Collections.Generic;
  4. using Newtonsoft.Json;
  5. using Newtonsoft.Json.Linq;
  6. namespace SmartBowSDK
  7. {
  8. public class CustomJson_SDK
  9. {
  10. public Dictionary<Type, Func<object, JToken>> importerDict = new Dictionary<Type, Func<object, JToken>>();
  11. public Dictionary<Type, Func<JToken, object>> exporterDict = new Dictionary<Type, Func<JToken, object>>();
  12. public CustomJson_SDK()
  13. {
  14. //add importer
  15. importerDict.Add(typeof(short), (o) => JValue.FromObject(o));
  16. importerDict.Add(typeof(int), (o) => JValue.FromObject(o));
  17. importerDict.Add(typeof(long), (o) => JValue.FromObject(o));
  18. importerDict.Add(typeof(float), (o) => JValue.FromObject(o));
  19. importerDict.Add(typeof(double), (o) => JValue.FromObject(o));
  20. importerDict.Add(typeof(bool), (o) => JValue.FromObject(o));
  21. importerDict.Add(typeof(double[][]), (o) => JArray.FromObject(o));
  22. importerDict.Add(typeof(Nullable<bool>), (o) => JValue.FromObject(o));
  23. //add exporter
  24. exporterDict.Add(typeof(short), (jt) => jt.ToObject<short>());
  25. exporterDict.Add(typeof(int), (jt) => jt.ToObject<int>());
  26. exporterDict.Add(typeof(long), (jt) => jt.ToObject<long>());
  27. exporterDict.Add(typeof(float), (jt) => jt.ToObject<float>());
  28. exporterDict.Add(typeof(double), (jt) => jt.ToObject<double>());
  29. exporterDict.Add(typeof(bool), (jt) => jt.ToObject<bool>());
  30. exporterDict.Add(typeof(double[][]), (jt) => ((JArray)jt).ToObject<double[][]>());
  31. exporterDict.Add(typeof(Nullable<bool>), (jt) => jt.ToObject<Nullable<bool>>());
  32. }
  33. public void InitJsonClass<T>(Func<object, JToken> importer, Func<JToken, object> exporter)
  34. {
  35. Type type = typeof(T);
  36. importerDict.Add(type, importer);
  37. exporterDict.Add(type, exporter);
  38. }
  39. public void InitJsonClass<T>(Func<object> ctor, params string[] props)
  40. {
  41. Type type = typeof(T);
  42. exporterDict.Add(type, (jt) =>
  43. {
  44. var o = ctor.Invoke();
  45. FetchFieldValues(o, jt, props);
  46. return o;
  47. });
  48. importerDict.Add(type, (o) =>
  49. {
  50. JToken jt = new JObject();
  51. FetchJsonProperties(jt, o, props);
  52. return jt;
  53. });
  54. }
  55. public T Parse<T>(string text)
  56. {
  57. var jt = JToken.Parse(text);
  58. return (T)ParseByExporter(jt, typeof(T));
  59. }
  60. public string Stringify(object o)
  61. {
  62. return JsonConvert.SerializeObject(ToJTokenByImporter(o));
  63. }
  64. public void FetchJsonProperties(JToken target, object fromObject, params string[] propertyNames)
  65. {
  66. Type fromObjectType = fromObject.GetType();
  67. foreach (var propertyName in propertyNames)
  68. {
  69. FieldInfo targetField = fromObjectType.GetField(propertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
  70. if (targetField == null)
  71. {
  72. PropertyInfo propertyInfo = fromObjectType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
  73. if (propertyInfo == null)
  74. {
  75. throw new Exception($"获取PropertyInfo[{propertyName}]失败");
  76. }
  77. else
  78. {
  79. JToken propertyValue = ToJTokenByImporter(propertyInfo.GetValue(fromObject));
  80. target[propertyName] = propertyValue;
  81. }
  82. }
  83. else
  84. {
  85. JToken propertyValue = ToJTokenByImporter(targetField.GetValue(fromObject));
  86. target[propertyName] = propertyValue;
  87. }
  88. }
  89. }
  90. public JToken ToJTokenByImporter(object o)
  91. {
  92. if (o == null) return null;
  93. Type type = o.GetType();
  94. Func<object, JToken> importer = null;
  95. importerDict.TryGetValue(type, out importer);
  96. if (importer == null)
  97. {
  98. if (IsArray(type) && type.GetArrayRank() == 1)
  99. { //是一维数组才会触发
  100. Type elemType = type.GetElementType();
  101. importerDict.TryGetValue(elemType, out importer);
  102. if (importer == null) throw new Exception($"缺少Type<{elemType.Name}>的Importer");
  103. JArray ja = new JArray();
  104. Array arr = (Array)o;
  105. for (int i = 0; i < arr.Length; i++) ja.Add(importer.Invoke(arr.GetValue(i)));
  106. return ja;
  107. }
  108. else
  109. {
  110. throw new Exception($"缺少Type<{type.Name}>的Importer");
  111. }
  112. }
  113. return importer.Invoke(o);
  114. }
  115. public T ParseByExporter<T>(JToken jt)
  116. {
  117. return (T)ParseByExporter(jt, typeof(T));
  118. }
  119. public object ParseByExporter(JToken jt, Type type)
  120. {
  121. if (jt.Type == JTokenType.Null) return null;
  122. Func<JToken, object> exporter = null;
  123. exporterDict.TryGetValue(type, out exporter);
  124. if (exporter == null)
  125. {
  126. if (IsArray(type) && type.GetArrayRank() == 1)
  127. { //是一维数组才会触发
  128. Type elemType = type.GetElementType();
  129. exporterDict.TryGetValue(elemType, out exporter);
  130. if (exporter == null) throw new Exception($"缺少Type<{elemType.Name}>的Exporter");
  131. var ja = (JArray)jt;
  132. var arr = Array.CreateInstance(elemType, ja.Count);
  133. for (int i = 0; i < arr.Length; i++) arr.SetValue(exporter.Invoke(ja[i]), i);
  134. return arr;
  135. }
  136. else
  137. {
  138. throw new Exception($"缺少Type<{type.Name}>的Exporter");
  139. }
  140. }
  141. return exporter.Invoke(jt);
  142. }
  143. public void FetchFieldValues(object target, JToken fromJson, params string[] fieldNames)
  144. {
  145. Type targetType = target.GetType();
  146. foreach (var fieldName in fieldNames)
  147. {
  148. FieldInfo targetField = targetType.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
  149. if (targetField == null)
  150. {
  151. PropertyInfo propertyInfo = targetType.GetProperty(fieldName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
  152. if (propertyInfo == null)
  153. {
  154. throw new Exception($"获取PropertyInfo[{fieldName}]失败");
  155. }
  156. else
  157. {
  158. object fieldValue = ParseByExporter(fromJson[fieldName], propertyInfo.PropertyType);
  159. propertyInfo.SetValue(target, fieldValue);
  160. }
  161. }
  162. else
  163. {
  164. object fieldValue = ParseByExporter(fromJson[fieldName], targetField.FieldType);
  165. targetField.SetValue(target, fieldValue);
  166. }
  167. }
  168. }
  169. public bool IsArray(Type type)
  170. {
  171. return type.BaseType == typeof(Array);
  172. }
  173. }
  174. }