CustomJson.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using System;
  2. using System.Reflection;
  3. using System.Collections.Generic;
  4. using Newtonsoft.Json;
  5. using Newtonsoft.Json.Linq;
  6. namespace JCUnityLib
  7. {
  8. public class CustomJson
  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()
  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. //add exporter
  23. exporterDict.Add(typeof(short), (jt) => jt.ToObject<short>());
  24. exporterDict.Add(typeof(int), (jt) => jt.ToObject<int>());
  25. exporterDict.Add(typeof(long), (jt) => jt.ToObject<long>());
  26. exporterDict.Add(typeof(float), (jt) => jt.ToObject<float>());
  27. exporterDict.Add(typeof(double), (jt) => jt.ToObject<double>());
  28. exporterDict.Add(typeof(bool), (jt) => jt.ToObject<bool>());
  29. exporterDict.Add(typeof(double[][]), (jt) => ((JArray)jt).ToObject<double[][]>());
  30. }
  31. public void InitJsonClass<T>(Func<object, JToken> importer, Func<JToken, object> exporter)
  32. {
  33. Type type = typeof(T);
  34. importerDict.Add(type, importer);
  35. exporterDict.Add(type, exporter);
  36. }
  37. public void InitJsonClass<T>(Func<object> ctor, params string[] props)
  38. {
  39. Type type = typeof(T);
  40. exporterDict.Add(type, (jt) => {
  41. var o = ctor.Invoke();
  42. FetchFieldValues(o, jt, props);
  43. return o;
  44. });
  45. importerDict.Add(type, (o) => {
  46. JToken jt = new JObject();
  47. FetchJsonProperties(jt, o, props);
  48. return jt;
  49. });
  50. }
  51. public T Parse<T>(string text)
  52. {
  53. var jt = JToken.Parse(text);
  54. return (T)ParseByExporter(jt, typeof(T));
  55. }
  56. public string Stringify(object o)
  57. {
  58. return JsonConvert.SerializeObject(ToJTokenByImporter(o));
  59. }
  60. public void FetchJsonProperties(JToken target, object fromObject, params string[] propertyNames)
  61. {
  62. Type fromObjectType = fromObject.GetType();
  63. foreach (var propertyName in propertyNames)
  64. {
  65. FieldInfo targetField = fromObjectType.GetField(propertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
  66. if (targetField == null) {
  67. PropertyInfo propertyInfo = fromObjectType.GetProperty(propertyName);
  68. JToken propertyValue = ToJTokenByImporter(propertyInfo.GetValue(fromObject));
  69. target[propertyName] = propertyValue;
  70. } else {
  71. JToken propertyValue = ToJTokenByImporter(targetField.GetValue(fromObject));
  72. target[propertyName] = propertyValue;
  73. }
  74. }
  75. }
  76. public JToken ToJTokenByImporter(object o)
  77. {
  78. Type type = o.GetType();
  79. Func<object, JToken> importer = null;
  80. importerDict.TryGetValue(type, out importer);
  81. if (importer == null) {
  82. if (IsArray(type) && type.GetArrayRank() == 1) { //是一维数组才会触发
  83. Type elemType = type.GetElementType();
  84. importerDict.TryGetValue(elemType, out importer);
  85. if (importer == null) throw new Exception($"缺少Type<{elemType.Name}>的Importer");
  86. JArray ja = new JArray();
  87. Array arr = (Array) o;
  88. for (int i = 0; i < arr.Length; i++) ja.Add(importer.Invoke(arr.GetValue(i)));
  89. return ja;
  90. } else {
  91. throw new Exception($"缺少Type<{type.Name}>的Importer");
  92. }
  93. }
  94. return importer.Invoke(o);
  95. }
  96. public T ParseByExporter<T>(JToken jt)
  97. {
  98. return (T)ParseByExporter(jt, typeof(T));
  99. }
  100. public object ParseByExporter(JToken jt, Type type)
  101. {
  102. Func<JToken, object> exporter = null;
  103. exporterDict.TryGetValue(type, out exporter);
  104. if (exporter == null) {
  105. if (IsArray(type) && type.GetArrayRank() == 1) { //是一维数组才会触发
  106. Type elemType = type.GetElementType();
  107. exporterDict.TryGetValue(elemType, out exporter);
  108. if (exporter == null) throw new Exception($"缺少Type<{elemType.Name}>的Exporter");
  109. var ja = (JArray) jt;
  110. var arr = Array.CreateInstance(elemType, ja.Count);
  111. for (int i = 0; i < arr.Length; i++) arr.SetValue(exporter.Invoke(ja[i]), i);
  112. return arr;
  113. } else {
  114. throw new Exception($"缺少Type<{type.Name}>的Exporter");
  115. }
  116. }
  117. return exporter.Invoke(jt);
  118. }
  119. public void FetchFieldValues(object target, JToken fromJson, params string[] fieldNames) {
  120. Type targetType = target.GetType();
  121. foreach (var fieldName in fieldNames)
  122. {
  123. FieldInfo targetField = targetType.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
  124. if (targetField == null) {
  125. PropertyInfo propertyInfo = targetType.GetProperty(fieldName);
  126. object fieldValue = ParseByExporter(fromJson[fieldName], propertyInfo.PropertyType);
  127. propertyInfo.SetValue(target, fieldValue);
  128. } else {
  129. object fieldValue = ParseByExporter(fromJson[fieldName], targetField.FieldType);
  130. targetField.SetValue(target, fieldValue);
  131. }
  132. }
  133. }
  134. public bool IsArray(Type type)
  135. {
  136. return type.BaseType == typeof(Array);
  137. }
  138. }
  139. }