NumberConverter.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using Newtonsoft.Json;
  2. using System;
  3. using System.ComponentModel;
  4. namespace JiaZhiQuan.Common.Response {
  5. public sealed class NumberConverter : JsonConverter {
  6. /// <summary>
  7. /// 转换成字符串的类型
  8. /// </summary>
  9. private readonly NumberConverterShip? _ship;
  10. private readonly string _format;
  11. /// <summary>
  12. /// 大数据json序列化重写实例化
  13. /// </summary>
  14. public NumberConverter() {
  15. }
  16. /// <summary>
  17. /// 大数据json序列化重写实例化
  18. /// </summary>
  19. /// <param name="ship">转换成字符串的类型</param>
  20. public NumberConverter(NumberConverterShip ship, string format=null) {
  21. _ship = ship;
  22. _format = format;
  23. }
  24. /// <inheritdoc />
  25. /// <summary>
  26. /// 确定此实例是否可以转换指定的对象类型。
  27. /// </summary>
  28. /// <param name="objectType">对象的类型。</param>
  29. /// <returns>如果此实例可以转换指定的对象类型,则为:<c>true</c>,否则为:<c>false</c></returns>
  30. public override bool CanConvert(Type objectType) {
  31. var typecode = Type.GetTypeCode(objectType.Name.Equals("Nullable`1") ?
  32. objectType.GetGenericArguments()[0] : objectType);
  33. return typecode switch {
  34. TypeCode.Decimal => _ship == null || (_ship & NumberConverterShip.Decimal) == NumberConverterShip.Decimal,
  35. TypeCode.Double => _ship == null || (_ship & NumberConverterShip.Double) == NumberConverterShip.Double,
  36. TypeCode.Int64 => _ship == null || (_ship & NumberConverterShip.Int64) == NumberConverterShip.Int64,
  37. TypeCode.UInt64 => _ship == null || (_ship & NumberConverterShip.UInt64) == NumberConverterShip.UInt64,
  38. TypeCode.Single => _ship == null || (_ship & NumberConverterShip.Single) == NumberConverterShip.Single,
  39. _ => false,
  40. };
  41. }
  42. /// <inheritdoc />
  43. /// <summary>
  44. /// 读取对象的JSON表示。
  45. /// </summary>
  46. /// <param name="reader">从 <see cref="T:Newtonsoft.Json.JsonReader" /> 中读取。</param>
  47. /// <param name="objectType">对象的类型。</param>
  48. /// <param name="existingValue">正在读取的对象的现有值。</param>
  49. /// <param name="serializer">调用的序列化器实例。</param>
  50. /// <returns>对象值。</returns>
  51. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
  52. return reader.Value == null ? null: AsType(reader.Value.ToString(), objectType);
  53. }
  54. /// <summary>
  55. /// 字符串格式数据转其他类型数据
  56. /// </summary>
  57. /// <param name="input">输入的字符串</param>
  58. /// <param name="destinationType">目标格式</param>
  59. /// <returns>转换结果</returns>
  60. public static object AsType(string input, Type destinationType) {
  61. try {
  62. var converter = TypeDescriptor.GetConverter(destinationType);
  63. if (converter.CanConvertFrom(typeof(string))) {
  64. return converter.ConvertFrom(null, null, input);
  65. }
  66. converter = TypeDescriptor.GetConverter(typeof(string));
  67. if (converter.CanConvertTo(destinationType)) {
  68. return converter.ConvertTo(null, null, input, destinationType);
  69. }
  70. } catch {
  71. return null;
  72. }
  73. return null;
  74. }
  75. /// <inheritdoc />
  76. /// <summary>
  77. /// 写入对象的JSON表示形式。
  78. /// </summary>
  79. /// <param name="writer">要写入的 <see cref="T:Newtonsoft.Json.JsonWriter" /> 。</param>
  80. /// <param name="value">要写入对象值</param>
  81. /// <param name="serializer">调用的序列化器实例。</param>
  82. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
  83. if (value == null) {
  84. writer.WriteNull();
  85. } else {
  86. var objectType = value.GetType();
  87. var typeCode = Type.GetTypeCode(objectType.Name.Equals("Nullable`1") ?
  88. objectType.GetGenericArguments()[0] : objectType);
  89. switch (typeCode) {
  90. case TypeCode.Decimal:
  91. writer.WriteValue(((decimal)value).ToString(_format ?? "f6"));
  92. break;
  93. case TypeCode.Double:
  94. writer.WriteValue(((double)value).ToString(_format ?? "f4"));
  95. break;
  96. case TypeCode.Single:
  97. writer.WriteValue(((float)value).ToString(_format ?? "f2"));
  98. break;
  99. case TypeCode.Int64:
  100. var typedInt64Value = (long)value;
  101. if (typedInt64Value < Int32.MaxValue && typedInt64Value > Int32.MinValue)
  102. {
  103. writer.WriteValue(typedInt64Value);
  104. }
  105. else
  106. {
  107. writer.WriteValue(value.ToString());
  108. }
  109. break;
  110. case TypeCode.UInt64:
  111. var typedUInt64Value = (ulong)value;
  112. if (typedUInt64Value < UInt32.MaxValue && typedUInt64Value > UInt32.MinValue)
  113. {
  114. writer.WriteValue(typedUInt64Value);
  115. }
  116. else
  117. {
  118. writer.WriteValue(value.ToString());
  119. }
  120. break;
  121. default:
  122. writer.WriteValue(value);
  123. break;
  124. }
  125. }
  126. }
  127. }
  128. /// <summary>
  129. /// 转换成字符串的类型
  130. /// </summary>
  131. [Flags]
  132. public enum NumberConverterShip {
  133. /// <summary>
  134. /// 长整数
  135. /// </summary>
  136. Int64 = 1,
  137. /// <summary>
  138. /// 无符号长整数
  139. /// </summary>
  140. UInt64 = 2,
  141. /// <summary>
  142. /// 浮点数
  143. /// </summary>
  144. Single = 4,
  145. /// <summary>
  146. /// 双精度浮点数
  147. /// </summary>
  148. Double = 8,
  149. /// <summary>
  150. /// 大数字
  151. /// </summary>
  152. Decimal = 16
  153. }
  154. }