『练手』手写一个独立Json算法 JsonHelper

背景:

> 一直使用 Newtonsoft.Json.dll 也算挺稳定的。

> 但这个框架也挺闹心的:

> 1、影响编译失败:https://www.cnblogs.com/zihuxinyu/archive/2013/05/06/3063181.html (我也经常遇到)

> 2、WinCE版本(小众用户)太大:Newtonsoft.Json.Compact.dll 352kb 

> 3、自己写一个微型框架,在通讯方面 要用到Json:一个 100k 的框架,引用一个 400k 的 Newtonsoft.Json.dll —— 总感觉 尾大不掉。

>4、不知道 目标类型,我只想将 Json反序列化成 List 和 Hash 的结构 —— 传说中的 万能结构,Newtonsoft.Json.dll 支持得不友好。

 

于是一咬牙,花 9个小时,手写了一个 Json算法:

> 基本支持 Newtonsoft.Json.dll 的 一切正反Json序列化:对象(字典)、集合、元数据。

> 可以将任意 Json 转换成 List 和 Hash 的 组合结构。

> 性能只有 Newtonsoft.Json.dll 的 1/3 (超长Json反序列化, JsonHelper:10000次/秒,Newtonsoft.Json.dll 性能是 30000次/秒)。

> 性能我已经满意了,源码 和 性能截图 如下。

 

性能测试截图:

超长Json反序列化:

JsonHelper 性能为 10W次 12.7秒,Newtonsoft.Json.dll 性能为 10W次 3.7秒。

 

手写一个嵌套实体 10W次 反序列化性能:

JsonHelper 性能为 10W次 7.8秒,Newtonsoft.Json.dll 性能为 10W次 1.3秒。

 

手写一个嵌套实体 10W次 序列化:

JsonHelper 性能为 10W次 2.6秒,Newtonsoft.Json.dll 性能为 10W次 1.2秒。

 

 

JsonHelper 源码:

   1 using System;
   2 using System.Collections;
   3 using System.Collections.Generic;
   4 using System.Collections.Specialized;
   5 using System.Globalization;
   6 using System.IO;
   7 using System.Linq;
   8 using System.Reflection;
   9 using System.Text;
  10 using System.Text.RegularExpressions;
  11 using Newtonsoft.Json.Linq;
  12 
  13 namespace InkFx.Utils
  14 {
  15     /// <summary>
  16     /// 不依赖 任何第三方JSON框架的 Json 辅助类
  17     /// </summary>
  18     public static class JsonHelper
  19     {
  20         #region  公 共 函 数
  21 
  22         /// <summary>
  23         /// 将指定对象转换成 JSON
  24         /// </summary>
  25         public static string JsonSerialize(object data)
  26         {
  27             return JsonSerialize(data, false);
  28         }
  29         /// <summary>
  30         /// 将指定对象转换成 JSON
  31         /// </summary>
  32         public static string JsonSerialize(object data, bool throwEeception)
  33         {
  34             if (data == null) return "null";
  35 
  36             try
  37             {
  38                 JsonObject obj = ObjectToJsonObject(data);
  39                 return obj == null ? "null" : obj.ToJson();
  40             }
  41             catch (Exception exp)
  42             {
  43                 if (throwEeception) throw;
  44                 else
  45                 {
  46                     string logMsg = "JsonHelper.JsonSerialize(object data) 序列化错误:" + exp;
  47                     Tools.LogError(logMsg, "Logs/Tools/ErrorLog/");
  48                     return null;
  49                 }
  50             }
  51         }
  52 
  53 
  54 
  55         /// <summary>
  56         /// 将JSON 转换成 指定类型对象 
  57         /// </summary>
  58         public static T JsonDeserialize<T>(string json)
  59         {
  60             return JsonDeserialize<T>(json, false);
  61         }
  62         /// <summary>
  63         /// 将JSON 转换成 指定类型对象 
  64         /// </summary>
  65         public static T JsonDeserialize<T>(string json, bool throwEeception)
  66         {
  67             if (IsNullOrWhiteSpace(json)) return default(T);
  68 
  69             try
  70             {
  71                 JsonObject obj = StringToJsonObject(json);
  72                 T result = JsonObjectToObject<T>(obj);
  73                 return (T)result;
  74             }
  75             catch (Exception exp)
  76             {
  77                 if (throwEeception) throw;
  78                 else
  79                 {
  80                     string logMsg = "JsonHelper.JsonDeserialize<T>(string json) 反序列化错误:" + exp;
  81                     Tools.LogError(logMsg, "Logs/Tools/ErrorLog/");
  82                     return default(T);
  83                 }
  84             }
  85         }
  86         /// <summary>
  87         /// 将JSON 转换成 指定类型对象 
  88         /// </summary>
  89         public static object JsonDeserialize(string json, Type type)
  90         {
  91             return JsonDeserialize(json, type, false);
  92         }
  93         /// <summary>
  94         /// 将JSON 转换成 指定类型对象 
  95         /// </summary>
  96         public static object JsonDeserialize(string json, Type type, bool throwEeception)
  97         {
  98             if (IsNullOrWhiteSpace(json)) return null;
  99 
 100             try
 101             {
 102                 JsonObject obj = StringToJsonObject(json);
 103                 object result = JsonObjectToObject(obj, type);
 104                 return result;
 105             }
 106             catch (Exception exp)
 107             {
 108                 if (throwEeception) throw;
 109                 else
 110                 {
 111                     string logMsg = "JsonHelper.JsonDeserialize(string json, Type type) 反序列化错误:" + exp;
 112                     Tools.LogError(logMsg, "Logs/Tools/ErrorLog/");
 113                     return null;
 114                 }
 115             }
 116         }
 117 
 118 
 119         /// <summary>
 120         /// 在 未指定 Json 反序列化类型 的情况下, 用 JsonObject 表达一个 Json对象
 121         /// </summary>
 122         public static JsonObject JsonDeserializeObject(string json)
 123         {
 124             return JsonDeserializeObject(json, false);
 125         }
 126         /// <summary>
 127         /// 在 未指定 Json 反序列化类型 的情况下, 用 JsonObject 表达一个 Json对象
 128         /// </summary>
 129         public static JsonObject JsonDeserializeObject(string json, bool throwEeception)
 130         {
 131             if (IsNullOrWhiteSpace(json)) return null;
 132 
 133             try
 134             {
 135                 JsonObject result = StringToJsonObject(json);
 136                 return result;
 137             }
 138             catch (Exception exp)
 139             {
 140                 if (throwEeception) throw;
 141                 else
 142                 {
 143                     string logMsg = "JsonHelper.JsonDeserializeObject(string json) 反序列化错误:" + exp;
 144                     Tools.LogError(logMsg, "Logs/Tools/ErrorLog/");
 145                     return null;
 146                 }
 147             }
 148         }
 149         /// <summary>
 150         /// 在 未指定 Json 反序列化类型 的情况下, 用 字典、集合 表达一个 Json对象
 151         /// </summary>
 152         public static object JsonDeserializeHasnList(string json)
 153         {
 154             return JsonDeserializeHasnList<Hashtable>(json, false);
 155         }
 156         /// <summary>
 157         /// 在 未指定 Json 反序列化类型 的情况下, 用 字典、集合 表达一个 Json对象
 158         /// </summary>
 159         public static object JsonDeserializeHasnList(string json, bool throwEeception)
 160         {
 161             return JsonDeserializeHasnList<Hashtable>(json, throwEeception);
 162         }
 163         /// <summary>
 164         /// 在 未指定 Json 反序列化类型 的情况下, 用 字典、集合 表达一个 Json对象
 165         /// </summary>
 166         public static object JsonDeserializeHasnList<HashT>(string json) where HashT : IDictionary, new()
 167         {
 168             return JsonDeserializeHasnList<HashT>(json, false);
 169         }
 170         /// <summary>
 171         /// 在 未指定 Json 反序列化类型 的情况下, 用 字典、集合 表达一个 Json对象
 172         /// </summary>
 173         public static object JsonDeserializeHasnList<HashT>(string json, bool throwEeception) where HashT : IDictionary, new()
 174         {
 175             if (IsNullOrWhiteSpace(json)) return null;
 176 
 177             try
 178             {
 179                 JsonObject obj = StringToJsonObject(json);
 180                 object result = obj.ToHashList<HashT>();
 181                 return result;
 182             }
 183             catch (Exception exp)
 184             {
 185                 if (throwEeception) throw;
 186                 else
 187                 {
 188                     string logMsg = "JsonHelper.JsonDeserializeHasnList(string json) 反序列化错误:" + exp;
 189                     Tools.LogError(logMsg, "Logs/Tools/ErrorLog/");
 190                     return null;
 191                 }
 192             }
 193         }
 194 
 195 
 196         /// <summary>
 197         /// 将 JsonObject 实体 分析成 指定的类型
 198         /// </summary>
 199         public static T JsonObjectToObject<T>(JsonObject obj)
 200         {
 201             if (obj == null) return default(T);
 202             object result = JsonObjectToObject(obj, typeof (T));
 203             return (T)result;
 204         }
 205         /// <summary>
 206         /// 将 JsonObject 实体 分析成 指定的类型
 207         /// </summary>
 208         public static object JsonObjectToObject(JsonObject obj, Type type)
 209         {
 210             if (obj == null) return null;
 211             return obj.ToObject(type);
 212         }
 213 
 214 
 215         #endregion
 216 
 217 
 218         #region  私 有 函 数
 219 
 220         private static DateTime m_StampRoot = new DateTime(1970, 01, 01, 00, 00, 00, 00, DateTimeKind.Utc);
 221         private static readonly Regex m_RegNum = new Regex(@"\d+", RegexOptions.Compiled | RegexOptions.IgnoreCase);
 222 
 223         /// <summary>
 224         /// Json时间戳 转 时间
 225         /// </summary>
 226         public static DateTime StampToDateTime(string timeStamp)
 227         {
 228             Match match = m_RegNum.Match(timeStamp);
 229             if (!match.Success) return m_StampRoot;
 230             long num = long.Parse(match.Value);
 231             return StampToDateTime(num);
 232         }
 233         /// <summary>
 234         /// Json时间戳 转 时间
 235         /// </summary>
 236         public static DateTime StampToDateTime(long timeStamp)
 237         {
 238             return m_StampRoot.AddMilliseconds(timeStamp).ToLocalTime();
 239         }
 240         /// <summary>
 241         /// 时间 转 Json时间戳
 242         /// </summary>
 243         public static long DateTimeToStamp(DateTime time)
 244         {
 245             return (long)(time.ToUniversalTime() - m_StampRoot).TotalMilliseconds;
 246         }
 247 
 248         private static bool IsNullOrWhiteSpace(string value)
 249         {
 250             if (value == null) return true;
 251             for (int i = 0; i < value.Length; i++)
 252                 if (!char.IsWhiteSpace(value[i]))
 253                     return false;
 254             return true;
 255         }
 256 
 257         #endregion
 258 
 259 
 260         #region  核 心 算 法
 261 
 262 
 263         private static JsonObject ObjectToJsonObject(object data)
 264         {
 265             if (data == null) return null;
 266 
 267             Type type = data.GetType();
 268 
 269             if (ReflectHelper.IsMetaType(type))
 270             {
 271                 return new JsonValue(data, false);
 272             }
 273             else if (data is IDictionary)
 274             {
 275                 JsonHash jsonHash = new JsonHash();
 276                 IDictionary hash = (IDictionary) data;
 277                 foreach (object key in hash.Keys)
 278                 {
 279                     object value = hash[key];
 280                     JsonObject jsonV = ObjectToJsonObject(value);
 281                     jsonHash[key.ToString()] = jsonV;
 282                 }
 283                 return jsonHash;
 284             }
 285             else if (data is IList)
 286             {
 287                 JsonList jsonList = new JsonList();
 288                 foreach (object item in (IList)data)
 289                 {
 290                     JsonObject jsonObj = ObjectToJsonObject(item);
 291                     if (jsonObj != null) jsonList.Add(jsonObj);
 292                 }
 293                 return jsonList;
 294             }
 295             else
 296             {
 297                 Hashtable hash = new Hashtable();
 298                 FieldInfo[] listField = type.GetFields();
 299                 PropertyInfo[] listProp = type.GetProperties();
 300                 foreach (FieldInfo field in listField)
 301                 {
 302                     object fieldObj = ReflectHelper.GetValue(data, field);
 303                     hash[field.Name] = fieldObj;
 304                 }
 305                 foreach (PropertyInfo prop in listProp)
 306                 {
 307                     object propObj = ReflectHelper.GetValue(data, prop);
 308                     hash[prop.Name] = propObj;
 309                 }
 310                 return ObjectToJsonObject(hash);
 311             }
 312         }
 313         private static JsonObject StringToJsonObject(string json)
 314         {
 315             List<JsonObject> queue = new List<JsonObject>();
 316             using (JsonReader reader = new JsonReader(json))
 317             {
 318                 while (!reader.IsEnd)
 319                 {
 320                     string item = reader.Read();
 321                     if (string.IsNullOrEmpty(item)) continue;
 322                     if (item.Length == 1)
 323                     {
 324                         char @char = item[0];
 325                         if (@char == ARRAY_BEGIN)
 326                         {
 327                             queue.Add(new JsonList());
 328                         }
 329                         else if (@char == OBJECT_BEGIN)
 330                         {
 331                             queue.Add(new JsonHash());
 332                         }
 333                         else if (@char == ITEM_SPLIT)
 334                         {
 335                             MergeLastJsonKeyValue(queue);
 336                         }
 337                         else if (@char == KV_SPLIT)
 338                         {
 339                             MergeLastJsonKeyValue(queue);
 340                             queue.Add(new JsonKeyValue());
 341                         }
 342                         else if (@char == ARRAY_END)
 343                         {
 344                             MergeLastJsonKeyValue(queue);
 345 
 346                             #region  搜索最近的一个数组开始
 347 
 348                             int index = queue.FindLastIndex(x => x.IsList);
 349                             JsonList array = (JsonList)queue[index];
 350                             for (int i = index + 1, count = queue.Count; i < count; i++) array.Add(queue[i]);
 351                             queue.RemoveRange(index + 1, queue.Count - index - 1);
 352 
 353                             #endregion
 354                         }
 355                         else if (@char == OBJECT_END)
 356                         {
 357                             MergeLastJsonKeyValue(queue);
 358 
 359                             #region  搜索最近的一个对象开始
 360 
 361                             int index = queue.FindLastIndex(x => x.IsHash);
 362                             JsonHash hash = (JsonHash)queue[index];
 363                             List<JsonObject> list = new List<JsonObject>();
 364                             for (int i = index + 1, count = queue.Count; i < count; i++) list.Add(queue[i]);
 365                             List<JsonObject> listKV = list.FindAll(x => (x is JsonKeyValue));
 366 
 367                             for (int i = 0, count = listKV.Count; i < count; i++)
 368                             {
 369                                 JsonKeyValue keyValue = (JsonKeyValue)listKV[i];
 370                                 hash.Hash[keyValue.Key.Value.ToString()] = keyValue.Value;
 371                             }
 372                             queue.RemoveRange(index + 1, queue.Count - index - 1);
 373 
 374                             #endregion
 375                         }
 376                     }
 377                     else
 378                     {
 379                         queue.Add(new JsonValue(item, true));
 380                     }
 381                 }
 382                 reader.Dispose();
 383             }
 384 
 385             int queueCount = queue.Count;
 386             if (queueCount == 1) return queue[0];
 387             if (queueCount >= 2)
 388             {
 389                 JsonList jsonList = new JsonList();
 390                 foreach (JsonObject item in queue) jsonList.Add(item);
 391                 return jsonList;
 392             }
 393 
 394             return null;
 395         }
 396         private static void MergeLastJsonKeyValue(List<JsonObject> queue)
 397         {
 398             if (queue == null || queue.Count <= 2) return;
 399             int count = queue.Count;
 400 
 401             if (queue[count - 2] is JsonKeyValue)
 402             {
 403                 //标准情况
 404                 JsonObject key = queue[count - 3];
 405                 if (!(key is JsonValue)) return;
 406                 JsonObject value = queue[count - 1];
 407                 JsonKeyValue keyValue = (JsonKeyValue)queue[count - 2];
 408                 keyValue.Key = (JsonValue)key;
 409                 keyValue.Value = value;
 410                 queue.RemoveAt(count - 1);
 411                 queue.RemoveAt(count - 3);
 412             }
 413             else if (queue[count - 1] is JsonKeyValue)
 414             {
 415                 //有键无值
 416                 JsonObject key = queue[count - 2];
 417                 if (!(key is JsonValue)) return;
 418                 JsonKeyValue keyValue = (JsonKeyValue)queue[count - 2];
 419                 keyValue.Key = (JsonValue)key;
 420                 queue.RemoveAt(count - 2);
 421             }
 422 
 423 
 424         }
 425 
 426 
 427 
 428 
 429 
 430         private const int ARRAY_BEGIN = '[';
 431         private const int ARRAY_END = ']';
 432         private const int OBJECT_BEGIN = '{';
 433         private const int OBJECT_END = '}';
 434         private const int ITEM_SPLIT = ',';
 435         private const int KV_SPLIT = ':';
 436         private const int STR_APOS = '\'';
 437         private const int STR_QUOT = '"';
 438         private const int STR_ESCAPE = '\\';
 439         private const int CHAR_SPACE = (int)' ';
 440         private const int CHAR_R = (int)'\r';
 441         private const int CHAR_N = (int)'\n';
 442         private const int CHAR_T = (int)'\t';
 443         private const int CHAR_A = (int)'\a';
 444         private const int CHAR_B = (int)'\b';
 445         private const int CHAR_F = (int)'\f';
 446         private const int CHAR_V = (int)'\v';
 447         private const int CHAR_0 = (int)'\0';
 448 
 449         private class JsonReader : IDisposable
 450         {
 451             public JsonReader(string json)
 452             {
 453                 //Json = FormatString(json);
 454                 Json = json;
 455                 Length = Json == null ? 0 : Json.Length;
 456             }
 457 
 458             private string Json = string.Empty;            
 459             private int Position = 0;
 460             private int Length = 0;
 461             internal bool IsEnd = false;
 462             
 463             /// <summary>
 464             /// 读取一个JSON的完整节点 字符串, 返回值可能有 [ ] { } , : String 
 465             /// </summary>
 466             /// <returns></returns>
 467             public string Read()
 468             {
 469                 if (Length <= 0 || Position >= Length) return string.Empty;
 470 
 471                 StringBuilder sb = new StringBuilder();
 472                 bool isApos = false, isQuot = false; int len = 0;
 473                  while (Position <= Length)
 474                 {
 475                     int p = Position;
 476                     char @char = Json[p];
 477                     int @charv = (int)@char;
 478                     Position++; IsEnd = Position >= Length; 
 479 
 480                     if (char.IsWhiteSpace(@char))
 481                     {
 482                         if (/*sb.Length <= 0*/len <= 0) { continue; } 
 483                         if (@charv != CHAR_SPACE && @charv != CHAR_R && @charv != CHAR_N && @charv != CHAR_T) { continue; } //转义符 仅保留 空格 \r \n \t 
 484                     }
 485 
 486                     sb.Append(@char); len++;
 487 
 488                     int @pcharv = (int)((p - 1 >= 0) ? Json[p - 1] : char.MinValue);
 489                     if (!isApos && !isQuot) { if (@charv == STR_APOS && @pcharv != STR_ESCAPE) { isApos = true; } else if (@charv == STR_QUOT && @pcharv != STR_ESCAPE) { isQuot = true; } }
 490                     else if ((isApos || isQuot) && /*sb.Length > 1*/ len > 1)
 491                     {
 492                         if (isApos && @charv == STR_APOS && @pcharv != STR_ESCAPE) { isApos = false; } 
 493                         else if (isQuot && @charv == STR_QUOT && @pcharv != STR_ESCAPE) { isQuot = false; }
 494                     }
 495 
 496                     if (!isApos && !isQuot)
 497                     {
 498                         if (IsConstChar(@charv)) break;
 499                         if (p + 1 < Length) { char @nchar = Json[p + 1]; if (IsConstChar((int)@nchar)) break; }
 500                     }
 501                 }
 502 
 503                 return sb.ToString().Trim();
 504             }
 505 
 506             private static bool IsConstChar(int @charv)
 507             {
 508                 return (@charv == ARRAY_BEGIN || @charv == ARRAY_END || @charv == OBJECT_BEGIN || @charv == OBJECT_END || @charv == ITEM_SPLIT || @charv == KV_SPLIT);
 509             }
 510             public void Dispose()
 511             {
 512                 Json = null;
 513                 Position = Length = 0;
 514             }
 515         }
 516 
 517         #endregion
 518 
 519 
 520 
 521 
 522 
 523 
 524 
 525 
 526     }
 527 
 528 
 529     #region  Json 实 体
 530 
 531     public abstract class JsonObject
 532     {
 533         public bool IsValue { get { return this is JsonValue; } }
 534         public bool IsList { get { return this is JsonList; } }
 535         public bool IsHash { get { return this is JsonHash; } }
 536         public bool IsKeyValue { get { return this is JsonKeyValue; } }
 537 
 538         public virtual string ToJson()
 539         {
 540             return ToJson(0, false);
 541         }
 542         public virtual string ToJson(int level)
 543         {
 544             return ToJson(level, false);
 545         }
 546         public abstract string ToJson(int level, bool format);
 547 
 548 
 549         public abstract object ToObject(Type type);
 550         public object ToHashList()
 551         {
 552             return InnerToHashList<Dictionary<string, object>>();
 553         }
 554         public object ToHashList<HashT>() where HashT : IDictionary, new()
 555         {
 556             return InnerToHashList<HashT>();
 557         }
 558         protected abstract object InnerToHashList<HashT>() where HashT : IDictionary, new();
 559 
 560         public override string ToString()
 561         {
 562             return ToJson(0, true);
 563         }
 564     }
 565     public class JsonValue : JsonObject
 566     {
 567         public JsonValue() { }
 568         public JsonValue(object value) : this(value, false)
 569         {
 570         }
 571         public JsonValue(object value, bool json)
 572         {
 573             this.m_Value = FmtValue(value, json);
 574         }
 575 
 576         private object m_Value = null;
 577 
 578         public string Json
 579         {
 580             get
 581             {
 582                 object value = m_Value;
 583                 //理论上这两行代码 不可达, 理论上 m_Value 不可能是 Json对象
 584                 if (value is JsonValue) return ((JsonValue)value).Json;
 585                 if (value is JsonObject) return ((JsonObject)value).ToJson();
 586 
 587                 if (m_Value == null) return "null";
 588                 if (m_Value is bool) return ((bool)m_Value).ToString().ToLower();
 589                 if (m_Value is Guid) return "\"" + ((Guid)m_Value).ToString("D") + "\"";
 590                 if (m_Value is DateTime) return "\"" + ((DateTime)m_Value).ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "\"";
 591                 if (m_Value is StringBuilder || m_Value is string || m_Value is char) return "\"" + StringToJsonString(m_Value.ToString()) + "\"";
 592                 if (m_Value is byte || m_Value is short || m_Value is int || m_Value is long || m_Value is sbyte || m_Value is ushort || m_Value is uint || m_Value is ulong) return m_Value.ToString();
 593                 if (m_Value is float || m_Value is double || m_Value is decimal) return m_Value.ToString();
 594 
 595                 //if (m_Value is float) return ((float)m_Value).ToString();
 596                 //if (m_Value is double) return ((double)m_Value).ToString();
 597                 //if (m_Value is decimal) return ((decimal)m_Value).ToString();
 598 
 599                 return "\"" + StringToJsonString(m_Value.ToString()) + "\"";
 600             }
 601         }
 602         public object Value
 603         {
 604             get { return m_Value; }
 605             set { this.m_Value = FmtValue(value, false); }
 606         }
 607 
 608         private static object FmtValue(object value, bool json)
 609         {
 610             if (value == null) { return null; }
 611             if (value is bool) { return (bool)value; }
 612             if (value is Guid) { return (Guid)value; }
 613             if (value is DateTime) { return (DateTime)value; }
 614             if (value is StringBuilder || value is string || value is char)
 615             {
 616                 string temp = value.ToString();
 617                 int len = temp.Length;
 618                 if (json && len >= 2 && temp[0] == '"' && temp[len - 1] == '"')
 619                 {
 620                     string str = JsonStringToString(temp.Substring(1, len - 2));
 621                     DateTime time; if (TryToDateTime(str, out time)) return time;
 622                     return str;
 623                 }
 624                 else if (json && len >= 2 && temp[0] == '\'' && temp[len - 1] == '\'')
 625                 {
 626                     string str = JsonStringToString(temp.Substring(1, len - 2));
 627                     DateTime time; if (TryToDateTime(str, out time)) return time;
 628                     return str;
 629                 }
 630                 else
 631                 {
 632                     if (json)
 633                     {
 634                         //bool float 不需要引号
 635                         string trim = temp.Trim();
 636                         string lower = trim.ToLower();
 637                         if (lower == "null") return null;
 638                         if (lower == "true") return true;
 639                         if (lower == "false") return false;
 640                         if (lower.StartsWith("new ")) return trim;
 641                         DateTime time; if (TryToDateTime(lower, out time)) return time;
 642                         double doub; if (double.TryParse(trim, out doub)) return doub;
 643                     }
 644 
 645                     return temp;
 646                 }
 647             }
 648             return value;
 649         }
 650         private static bool TryToDateTime(string source, out DateTime time)
 651         {
 652             try
 653             {
 654                 string lower = source.ToLower();
 655                 if (lower.StartsWith("/date(") || lower.StartsWith("date(") || lower.StartsWith("\\/date("))
 656                 {
 657                     //兼容微软最初的 Json时间格式   "Birthday":"\/Date(734840435887)\/" 
 658                     time = JsonHelper.StampToDateTime(lower);
 659                     return (time != DateTime.MinValue);
 660                 }
 661             }
 662             catch (Exception) { }
 663             time = DateTime.MinValue;
 664             return false;
 665         }
 666 
 667 
 668 
 669 
 670 
 671         public override object ToObject(Type type)
 672         {
 673             if (type == null || type == typeof (object)) return Value;
 674             return ReflectHelper.ChangeType(Value, type);
 675         }
 676         public override string ToJson(int level, bool format)
 677         {
 678             //return new string(' ', level*2) + Value;
 679             return Json;
 680         }
 681         protected override object InnerToHashList<HashT>()
 682         {
 683             if (Value == null) return null;
 684             if (Value is JsonObject) return ((JsonObject)Value).ToHashList<HashT>();
 685             return Value;
 686         }
 687 
 688 
 689         private static string JsonStringToString(string json)
 690         {
 691             if (string.IsNullOrEmpty(json)) return string.Empty;
 692             StringBuilder sb = new StringBuilder();
 693             for (int i = 0, c = json.Length; i < c; i++)
 694             {
 695                 char @char = json[i];
 696                 if (@char != '\\') { sb.Append(@char); continue; }
 697                 if (i + 1 >= c) { sb.Append(@char); continue; }
 698                 char @charn = json[i + 1];
 699                 if (@charn == '\\') { sb.Append('\\'); i++; continue; }
 700                 if (@charn == 'r') { sb.Append('\r'); i++; continue; }
 701                 if (@charn == 'n') { sb.Append('\n'); i++; continue; }
 702                 if (@charn == 't') { sb.Append('\t'); i++; continue; }
 703                 if (@charn == 'a') { sb.Append('\a'); i++; continue; }
 704                 if (@charn == 'b') { sb.Append('\b'); i++; continue; }
 705                 if (@charn == 'f') { sb.Append('\f'); i++; continue; }
 706                 if (@charn == 'v') { sb.Append('\v'); i++; continue; }
 707                 if (@charn == '"') { sb.Append('"'); i++; continue; }
 708                 if (@charn == '\'') { sb.Append('\''); i++; continue; }
 709                 if (@charn == '0') { /*sb.Append('\0');*/ i++; continue; }  // \0字符直接排除
 710 
 711                 if (@charn == 'u')
 712                 {
 713                     //\uFFFF 一是 Unicode 字符, 这类字符 一般是 4位 \uFFFF, 但是理论上 可以有5位 \uFFFFF
 714                     string hex = json.Substring(i + 2, 4);
 715                     //char h5 = json[i + 2 + 4];
 716                     //bool isHex5 = (h5 == '0' || h5 == '1' || h5 == '2' || h5 == '3' || h5 == '4' || h5 == '5' || h5 == '6' || h5 == '7' || h5 == '8' || h5 == '9' || h5 == 'a' || h5 == 'b' || h5 == 'c' || h5 == 'd' || h5 == 'e' || h5 == 'f' || h5 == 'A' || h5 == 'B' || h5 == 'C' || h5 == 'D' || h5 == 'E' || h5 == 'F');
 717                     //if (isHex5) hex = hex + h5;
 718                     int num;
 719                     if (int.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out num))
 720                     {
 721                         sb.Append((char)num); i = i + 5; /*if (isHex5){i++;} */continue;
 722                     }
 723                     else { sb.Append("\\u"); i++; continue; }
 724                 }
 725             }
 726             return sb.ToString();
 727         }
 728         internal static string StringToJsonString(string str)
 729         {
 730             if (string.IsNullOrEmpty(str)) return string.Empty;
 731 
 732             StringBuilder sb = new StringBuilder();
 733             for (int i = 0, c = str.Length; i < c; i++)
 734             {
 735                 char @char = str[i];
 736                 //if (@char == '\'') { sb.Append("\\'"); continue; } //单引号不再进行转义
 737                 if (@char == '"') { sb.Append("\\\""); continue; }
 738                 if (@char == '\\') { sb.Append("\\\\"); continue; }
 739                 if (@char == '\r') { sb.Append("\\r"); continue; }
 740                 if (@char == '\n') { sb.Append("\\n"); continue; }
 741                 if (@char == '\t') { sb.Append("\\t"); continue; }
 742                 if (@char == '\a') { sb.Append("\\a"); continue; }
 743                 if (@char == '\b') { sb.Append("\\b"); continue; }
 744                 if (@char == '\f') { sb.Append("\\f"); continue; }
 745                 if (@char == '\v') { sb.Append("\\v"); continue; }
 746                 if (@char == '\0') { /*sb.Append('\\\0');*/ continue; }  // \0字符直接排除
 747                 sb.Append(@char);
 748             }
 749             return sb.ToString();
 750         }
 751     }
 752     public class JsonKeyValue : JsonObject
 753     {
 754         public JsonKeyValue() { }
 755         public JsonKeyValue(JsonValue key, JsonObject value) { this.Key = key; this.Value = value; }
 756 
 757         public JsonValue Key { get; set; }
 758         public JsonObject Value { get; set; }
 759 
 760         public override object ToObject(Type type)
 761         {
 762             object obj = Activator.CreateInstance(type);
 763 
 764             ReflectHelper.SetValue(obj, "Key", (Key == null ? string.Empty : Key.Value.ToString()));
 765 
 766             Type propOrFieldType = ReflectHelper.GetPropertyOrFieldType(type, "Value");
 767             object value = (Value == null ? null : Value.ToObject(propOrFieldType));
 768             ReflectHelper.SetValue(obj, "Value", value);
 769 
 770             return obj;
 771         }
 772         public override string ToJson(int level, bool format)
 773         {
 774             return string.Format((format ? @"{0}: {1}" : @"{0}:{1}"), (Key == null ? string.Empty : Key.ToJson(0, false)), (Value == null ? "null" : Value.ToJson(level, format)));
 775         }
 776         public new KeyValuePair<string, object> ToHashList()
 777         {
 778             return (KeyValuePair<string, object>)InnerToHashList<Dictionary<string, object>>();
 779         }
 780         public new KeyValuePair<string, object> ToHashList<HashT>() where HashT : IDictionary, new()
 781         {
 782             return (KeyValuePair<string, object>)InnerToHashList<HashT>();
 783         }
 784         protected override object InnerToHashList<HashT>()
 785         {
 786             return new KeyValuePair<string, object>((Key == null ? string.Empty : Key.Value.ToString()), (Value == null ? null : Value.ToHashList<HashT>()));
 787         }
 788     }
 789     public class JsonList : JsonObject, IList, IList<JsonObject>
 790     {
 791         public bool HasValues { get; set; }
 792 
 793         [NonSerialized]
 794         private List<JsonObject> m_List;
 795         private List<JsonObject> List
 796         {
 797             get { return m_List ?? (m_List = new List<JsonObject>()); }
 798         }
 799 
 800 
 801         public int Count
 802         {
 803             get { return this.List.Count; }
 804         }
 805         public JsonObject this[int index]
 806         {
 807             get { return this.List[index]; }
 808             set { this.List[index] = value; }
 809         }
 810         public void Add(JsonObject item)
 811         {
 812             this.List.Add(item);
 813         }
 814         public void Insert(int index, JsonObject item)
 815         {
 816             this.List.Insert(index, item);
 817         }
 818         public void Remove(JsonObject item)
 819         {
 820             this.List.Remove(item);
 821         }
 822         public void RemoveAt(int index)
 823         {
 824             this.List.RemoveAt(index);
 825         }
 826         public void Clear()
 827         {
 828             this.List.Clear();
 829         }
 830         public bool Contains(JsonObject item)
 831         {
 832             return this.List.Contains(item);
 833         }
 834         public int IndexOf(JsonObject item)
 835         {
 836             return this.List.IndexOf(item);
 837         }
 838         public void CopyTo(JsonObject[] array, int arrayIndex)
 839         {
 840             this.List.CopyTo(array, arrayIndex);
 841         }
 842 
 843 
 844 
 845         public override object ToObject(Type type)
 846         {
 847             if (m_List == null) return null;
 848 
 849             Type listType = null;
 850             Type itemType = null;
 851             int sign = 0;
 852             if (type.IsArray) { listType = type; itemType = listType.GetElementType(); sign = 3; }
 853             else if (typeof(IList<>).IsAssignableFrom(type)) { listType = type; itemType = GetListElementType(listType); sign = 2; }
 854             else if (typeof(IList).IsAssignableFrom(type)) { listType = type; itemType = typeof(object); sign = 1; }
 855             else { listType = typeof(List<>).MakeGenericType(type); itemType = type; sign = 0; }
 856 
 857             if (sign < 0 || listType == null || ((sign == 2 || sign == 3) && listType.IsGenericTypeDefinition)) 
 858                 throw new Exception(string.Format("JsonList 无法反序列化得到类型: {0}", type.FullName));
 859 
 860             int count = (m_List != null) ? m_List.Count : 0;
 861             if (sign == 0 || sign == 1 || sign == 2)
 862             {
 863                 IList list = (IList)Activator.CreateInstance(listType);
 864                 if (count >= 1)
 865                     foreach (JsonObject item in m_List)
 866                     {
 867                         object obj = item.ToObject(itemType);
 868                         list.Add(obj);
 869                     }
 870                 return list;
 871             }
 872             else if (sign == 3)
 873             {
 874                 Array array = Array.CreateInstance(itemType, count);
 875                 if (count >= 1)
 876                     for (int i = 0; i < count; i++)
 877                     {
 878                         JsonObject item = m_List[i];
 879                         object obj = item.ToObject(itemType);
 880                         array.SetValue(obj, i);
 881                     }
 882                 return array;
 883             }
 884 
 885             return null;
 886         }
 887         public override string ToJson(int level, bool format)
 888         {
 889             string rn = !format ? string.Empty : "\r\n";
 890             string prev = !format ? string.Empty : new string(' ', (level) * 2);
 891             string prev2 = !format ? string.Empty : new string(' ', (level + 1) * 2);
 892             StringBuilder sb = new StringBuilder();
 893             sb.Append("[" + rn);
 894             if (m_List != null)
 895             {
 896                 List<string> list = new List<string>();
 897                 foreach (JsonObject item in m_List)
 898                     list.Add(prev2 + item.ToJson(level + 1, format));
 899 
 900                 for (int i = 0, count = list.Count; i < count; i++)
 901                     sb.Append(list[i] + (i == count - 1 ? string.Empty : ",") + rn);
 902             }
 903             sb.Append(prev + "]");
 904             return sb.ToString();
 905         }
 906         public new List<object> ToHashList()
 907         {
 908             return (List<object>)InnerToHashList<Dictionary<string, object>>();
 909         }
 910         public new List<object> ToHashList<HashT>() where HashT : IDictionary, new()
 911         {
 912             return (List<object>)InnerToHashList<HashT>();
 913         }
 914         protected override object InnerToHashList<HashT>()
 915         {
 916             if (m_List == null) return null;
 917 
 918             List<object> list = new List<object>();
 919             foreach (JsonObject item in m_List)
 920                 list.Add(item.ToHashList<HashT>());
 921             return list;
 922         }
 923 
 924 
 925         /// <summary>
 926         /// 查找指定 List类型, 对应的 集合成员类型
 927         /// </summary>
 928         public static Type GetListElementType(Type listType)
 929         {
 930             Type baseType = listType;
 931             Type[] itfsTypes = baseType.GetInterfaces();
 932             foreach (Type itfsType in itfsTypes)
 933             {
 934                 if (itfsType.IsGenericType && !itfsType.IsGenericTypeDefinition && typeof(IList<>) == itfsType.GetGenericTypeDefinition())
 935                 {
 936                     Type[] genericTypes = itfsType.GetGenericArguments();
 937                     if (genericTypes.Length == 1) return genericTypes[0];
 938                 }
 939             }
 940 
 941             foreach (Type itfsType in itfsTypes)
 942             {
 943                 if (itfsType.IsGenericType && !itfsType.IsGenericTypeDefinition && typeof(ICollection<>) == itfsType.GetGenericTypeDefinition())
 944                 {
 945                     Type[] genericTypes = itfsType.GetGenericArguments();
 946                     if (genericTypes.Length == 1) return genericTypes[0];
 947                 }
 948             }
 949 
 950             if (typeof(IList).IsAssignableFrom(listType)) { return typeof(object); }
 951             return null;
 952         }
 953      
 954 
 955         #region  中转的继承
 956 
 957         IEnumerator<JsonObject> IEnumerable<JsonObject>.GetEnumerator()
 958         {
 959             return ((IEnumerable<JsonObject>)this.List).GetEnumerator();
 960         }
 961         IEnumerator IEnumerable.GetEnumerator()
 962         {
 963             return ((IEnumerable)this.List).GetEnumerator();
 964         }
 965         void ICollection.CopyTo(Array array, int index)
 966         {
 967             ((ICollection)this.List).CopyTo(array, index);
 968         }
 969         bool ICollection<JsonObject>.Remove(JsonObject item)
 970         {
 971             return ((ICollection<JsonObject>)this.List).Remove(item);
 972         }
 973         int ICollection<JsonObject>.Count
 974         {
 975             get { return ((ICollection<JsonObject>)this.List).Count; }
 976         }
 977         bool ICollection<JsonObject>.IsReadOnly
 978         {
 979             get { return ((ICollection<JsonObject>)this.List).IsReadOnly; }
 980         }
 981         int ICollection.Count
 982         {
 983             get { return ((ICollection)this.List).Count; }
 984         }
 985         object ICollection.SyncRoot
 986         {
 987             get { return ((ICollection)this.List).SyncRoot; }
 988         }
 989         bool ICollection.IsSynchronized
 990         {
 991             get { return ((ICollection)this.List).IsSynchronized; }
 992         }
 993         int IList.Add(object value)
 994         {
 995             return ((IList)this.List).Add(value);
 996         }
 997         bool IList.Contains(object value)
 998         {
 999             return ((IList)this.List).Contains(value);
1000         }
1001         void ICollection<JsonObject>.Add(JsonObject item)
1002         {
1003             ((ICollection<JsonObject>)this.List).Add(item);
1004         }
1005         void ICollection<JsonObject>.Clear()
1006         {
1007             ((ICollection<JsonObject>)this.List).Clear();
1008         }
1009         bool ICollection<JsonObject>.Contains(JsonObject item)
1010         {
1011             return ((ICollection<JsonObject>)this.List).Contains(item);
1012         }
1013         void ICollection<JsonObject>.CopyTo(JsonObject[] array, int arrayIndex)
1014         {
1015             ((ICollection<JsonObject>)this.List).CopyTo(array, arrayIndex);
1016         }
1017         void IList.Clear()
1018         {
1019             ((IList)this.List).Clear();
1020         }
1021         int IList.IndexOf(object value)
1022         {
1023             return ((IList)this.List).IndexOf(value);
1024         }
1025         void IList.Insert(int index, object value)
1026         {
1027             ((IList)this.List).Insert(index, value);
1028         }
1029         void IList.Remove(object value)
1030         {
1031             ((IList)this.List).Remove(value);
1032         }
1033         int IList<JsonObject>.IndexOf(JsonObject item)
1034         {
1035             return ((IList<JsonObject>)this.List).IndexOf(item);
1036         }
1037         void IList<JsonObject>.Insert(int index, JsonObject item)
1038         {
1039             ((IList<JsonObject>)this.List).Insert(index, item);
1040         }
1041         void IList<JsonObject>.RemoveAt(int index)
1042         {
1043             ((IList<JsonObject>)this.List).RemoveAt(index);
1044         }
1045         JsonObject IList<JsonObject>.this[int index]
1046         {
1047             get { return ((IList<JsonObject>)this.List)[index]; }
1048             set { ((IList<JsonObject>)this.List)[index] = value; }
1049         }
1050         void IList.RemoveAt(int index)
1051         {
1052             ((IList)this.List).RemoveAt(index);
1053         }
1054         object IList.this[int index]
1055         {
1056             get { return ((IList)this.List)[index]; }
1057             set { ((IList)this.List)[index]=value; }
1058         }
1059         bool IList.IsReadOnly
1060         {
1061             get { return ((IList)this.List).IsReadOnly; }
1062         }
1063         bool IList.IsFixedSize
1064         {
1065             get { return ((IList)this.List).IsFixedSize; }
1066         }
1067 
1068         #endregion
1069     }
1070     public class JsonHash : JsonObject, IDictionary, IDictionary<string, JsonObject>
1071     {
1072         public bool HasValues { get; set; }
1073 
1074         [NonSerialized]
1075         private Dictionary<string, JsonObject> m_Hash;
1076         public Dictionary<string, JsonObject> Hash
1077         {
1078             get { return m_Hash ?? (m_Hash = new Dictionary<string, JsonObject>()); }
1079         }
1080 
1081 
1082         public JsonObject this[string key]
1083         {
1084             get
1085             {
1086                 if (m_Hash == null || m_Hash.Count <= 0) return null;
1087                 JsonObject value;
1088                 if (m_Hash.TryGetValue(key, out value)) return value;
1089                 return null;
1090             }
1091             set
1092             {
1093                 if (key == null) return;
1094                 if (!this.Hash.ContainsKey(key)) this.Hash.Add(key, value);
1095                 else this.Hash[key] = value;
1096             }
1097         }
1098         public int Count
1099         {
1100             get { return this.Hash.Count; }
1101         }
1102         public void Add(string key, JsonObject value)
1103         {
1104             this.Hash.Add(key, value);
1105         }
1106         public void Remove(string key)
1107         {
1108             this.Hash.Remove(key);
1109         }
1110         public void Clear()
1111         {
1112             this.Hash.Clear();
1113         }
1114         public bool ContainsKey(string key)
1115         {
1116             return this.Hash.ContainsKey(key);
1117         }
1118         public bool TryGetValue(string key, out JsonObject value)
1119         {
1120             return this.Hash.TryGetValue(key, out value);
1121         }
1122         public ICollection<string> Keys
1123         {
1124             get { return this.Hash.Keys; }
1125         }
1126         public ICollection<JsonObject> Values
1127         {
1128             get { return this.Hash.Values; }
1129         }
1130 
1131 
1132 
1133         public override object ToObject(Type type)
1134         {
1135             if (m_Hash == null) return null;
1136 
1137             int sign = 0;
1138             if (type == null || type == typeof(object) || typeof(IDictionary).IsAssignableFrom(type)) { if (type == null || type == typeof(object)) { type = typeof(Hashtable); } sign = 1; }
1139             else { sign = 0; }
1140 
1141             if (sign < 0 || (sign == 1 && type.IsGenericTypeDefinition))
1142                 throw new Exception(string.Format("JsonHash 无法反序列化得到类型: {0}", type.FullName));
1143 
1144             int count = (m_Hash != null) ? m_Hash.Count : 0;
1145             if (sign == 1)
1146             {
1147                 IDictionary hash = (IDictionary)Activator.CreateInstance(type);
1148                 if (count >= 1)
1149                     foreach (KeyValuePair<string, JsonObject> pair in m_Hash)
1150                     {
1151                         object obj = pair.Value.ToObject(typeof(object));
1152                         if (hash.Contains(pair.Key)) hash[pair.Key] = obj;
1153                         else hash.Add(pair.Key, obj);
1154                     }
1155                 return hash;
1156             }
1157             else if (sign == 0)
1158             {
1159                 object hash = Activator.CreateInstance(type);
1160                 if (count >= 1)
1161                     foreach (KeyValuePair<string, JsonObject> pair in m_Hash)
1162                     {
1163                         string key = pair.Key;
1164                         Type propOrFieldType = ReflectHelper.GetPropertyOrFieldType(type, key);
1165                         object value = (pair.Value == null ? null : pair.Value.ToObject(propOrFieldType));
1166                         ReflectHelper.SetValue(hash, key, value);
1167                     }
1168                 return hash;
1169             }
1170 
1171             return null;
1172         }
1173 
1174         public override string ToJson(int level, bool format)
1175         {
1176             string rn = !format ? string.Empty : "\r\n";
1177             string prev = !format ? string.Empty : new string(' ', (level) * 2);
1178             string prev2 = !format ? string.Empty : new string(' ', (level + 1) * 2);
1179             StringBuilder sb = new StringBuilder();
1180             sb.Append("{" + rn);
1181             if (m_Hash != null)
1182             {
1183                 List<string> list = new List<string>();
1184                 foreach (KeyValuePair<string, JsonObject> pair in m_Hash)
1185                     list.Add(prev2 + string.Format((format ? @"""{0}"": {1}" : @"""{0}"":{1}"), (pair.Key ?? string.Empty), (pair.Value == null ? "null" : pair.Value.ToJson(level + 1, format))));
1186 
1187                 for (int i = 0, count = list.Count; i < count; i++)
1188                     sb.Append(list[i] + (i == count - 1 ? string.Empty : ",") + rn);
1189             }
1190             sb.Append(prev + "}");
1191             return sb.ToString();
1192         }
1193         public new Dictionary<string, object> ToHashList()
1194         {
1195             return (Dictionary<string, object>)InnerToHashList<Dictionary<string, object>>();
1196         }
1197         public new HashT ToHashList<HashT>() where HashT : IDictionary, new()
1198         {
1199             return (HashT)InnerToHashList<HashT>();
1200         }
1201         protected override object InnerToHashList<HashT>()
1202         {
1203             if (m_Hash == null) return null;
1204 
1205             HashT hash = new HashT();
1206             foreach (KeyValuePair<string, JsonObject> pair in m_Hash)
1207             {
1208                 if (hash.Contains(pair.Key)) hash[pair.Key] = pair.Value.ToHashList<HashT>();
1209                 else hash.Add(pair.Key, pair.Value.ToHashList<HashT>());
1210             }
1211             return hash;
1212         }
1213 
1214 
1215         #region  中转的继承
1216 
1217         bool IDictionary.Contains(object key)
1218         {
1219             return ((IDictionary)this.Hash).Contains(key);
1220         }
1221         void IDictionary.Add(object key, object value)
1222         {
1223             ((IDictionary)this.Hash).Add(key, value);
1224         }
1225         void ICollection<KeyValuePair<string, JsonObject>>.Add(KeyValuePair<string, JsonObject> item)
1226         {
1227             ((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).Add(item);
1228         }
1229         void ICollection<KeyValuePair<string, JsonObject>>.Clear()
1230         {
1231             ((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).Clear();
1232         }
1233         bool ICollection<KeyValuePair<string, JsonObject>>.Contains(KeyValuePair<string, JsonObject> item)
1234         {
1235             return ((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).Contains(item);
1236         }
1237         void ICollection<KeyValuePair<string, JsonObject>>.CopyTo(KeyValuePair<string, JsonObject>[] array, int arrayIndex)
1238         {
1239             ((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).CopyTo(array, arrayIndex);
1240         }
1241         bool ICollection<KeyValuePair<string, JsonObject>>.Remove(KeyValuePair<string, JsonObject> item)
1242         {
1243             return ((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).Remove(item);
1244         }
1245         int ICollection<KeyValuePair<string, JsonObject>>.Count
1246         {
1247             get { return ((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).Count; }
1248         }
1249         bool ICollection<KeyValuePair<string, JsonObject>>.IsReadOnly
1250         {
1251             get { return ((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).IsReadOnly; }
1252         }
1253         void IDictionary.Clear()
1254         {
1255             ((IDictionary)this.Hash).Clear();
1256         }
1257         IEnumerator<KeyValuePair<string, JsonObject>> IEnumerable<KeyValuePair<string, JsonObject>>.GetEnumerator()
1258         {
1259             return ((IEnumerable<KeyValuePair<string, JsonObject>>)this.Hash).GetEnumerator();
1260         }
1261         IDictionaryEnumerator IDictionary.GetEnumerator()
1262         {
1263             return ((IDictionary)this.Hash).GetEnumerator();
1264         }
1265         void IDictionary.Remove(object key)
1266         {
1267             ((IDictionary)this.Hash).Remove(key);
1268         }
1269         object IDictionary.this[object key]
1270         {
1271             get { return ((IDictionary)this.Hash)[key]; }
1272             set { ((IDictionary)this.Hash)[key] = value; }
1273         }
1274         bool IDictionary<string, JsonObject>.ContainsKey(string key)
1275         {
1276             return ((IDictionary<string, JsonObject>)this.Hash).ContainsKey(key);
1277         }
1278         void IDictionary<string, JsonObject>.Add(string key, JsonObject value)
1279         {
1280             ((IDictionary<string, JsonObject>)this.Hash).Add(key, value);
1281         }
1282         bool IDictionary<string, JsonObject>.Remove(string key)
1283         {
1284             return ((IDictionary<string, JsonObject>)this.Hash).Remove(key);
1285         }
1286         bool IDictionary<string, JsonObject>.TryGetValue(string key, out JsonObject value)
1287         {
1288             return ((IDictionary<string, JsonObject>)this.Hash).TryGetValue(key, out value);
1289         }
1290         JsonObject IDictionary<string, JsonObject>.this[string key]
1291         {
1292             get { return ((IDictionary<string, JsonObject>)this.Hash)[key]; }
1293             set { ((IDictionary<string, JsonObject>)this.Hash)[key] = value; }
1294         }
1295         ICollection IDictionary.Keys
1296         {
1297             get { return ((IDictionary)this.Hash).Keys; }
1298         }
1299         ICollection<JsonObject> IDictionary<string, JsonObject>.Values
1300         {
1301             get { return ((IDictionary<string, JsonObject>)this.Hash).Values; }
1302         }
1303         ICollection<string> IDictionary<string, JsonObject>.Keys
1304         {
1305             get { return ((IDictionary<string, JsonObject>)this.Hash).Keys; }
1306         }
1307         ICollection IDictionary.Values
1308         {
1309             get { return ((IDictionary)this.Hash).Values; }
1310         }
1311         bool IDictionary.IsReadOnly
1312         {
1313             get { return ((IDictionary)this.Hash).IsReadOnly; }
1314         }
1315         bool IDictionary.IsFixedSize
1316         {
1317             get { return ((IDictionary)this.Hash).IsFixedSize; }
1318         }
1319         IEnumerator IEnumerable.GetEnumerator()
1320         {
1321             return ((IEnumerable)this.Hash).GetEnumerator();
1322         }
1323         void ICollection.CopyTo(Array array, int index)
1324         {
1325             ((ICollection)this.Hash).CopyTo(array, index);
1326         }
1327         int ICollection.Count
1328         {
1329             get { return ((ICollection)this.Hash).Count; }
1330         }
1331         object ICollection.SyncRoot
1332         {
1333             get { return ((ICollection)this.Hash).SyncRoot; }
1334         }
1335         bool ICollection.IsSynchronized
1336         {
1337             get { return ((ICollection)this.Hash).IsSynchronized; }
1338         }
1339 
1340         #endregion
1341     }
1342 
1343     #endregion
1344 }
View Code

 

JsonHelper_Test 源码:

  1 using System;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System.IO;
  5 using System.Linq;
  6 using System.Text;
  7 using System.Web.Script.Serialization;
  8 using InkFx.Utils.Test.Properties;
  9 using NUnit.Framework;
 10 
 11 namespace InkFx.Utils.Test
 12 {
 13     public class Test_JsonHelper
 14     {
 15         [Test]
 16         public void TestDeserialize()
 17         {
 18             string json = Resources.TestObjectJson2.Trim();
 19 
 20             JsonObject jsonObj = JsonHelper.JsonDeserializeObject(json);
 21             DateTime beginTime = DateTime.Now;
 22             for (int i = 0; i < 100000; i++)
 23             {
 24                 jsonObj = JsonHelper.JsonDeserializeObject(json);
 25             }
 26             DateTime endTime = DateTime.Now;
 27             Console.WriteLine(@"耗时: " + (endTime - beginTime).TotalMilliseconds);
 28             Console.WriteLine(jsonObj);
 29             Console.WriteLine(jsonObj.ToJson());
 30             Console.WriteLine(jsonObj.ToHashList());
 31         }
 32         [Test]
 33         public void TestDeserialize2()
 34         {
 35             string json = Resources.TestObjectJson2.Trim();
 36 
 37             DateTime beginTime = DateTime.Now;
 38             object jsonObj = null;
 39             for (int i = 0; i < 100000; i++)
 40             {
 41                 jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
 42             }
 43             DateTime endTime = DateTime.Now;
 44             Console.WriteLine(@"耗时: " + (endTime - beginTime).TotalMilliseconds);
 45             Console.WriteLine(jsonObj);
 46         }
 47 
 48 
 49         [Test]
 50         public void TestSerializeMetaValue()
 51         {
 52             Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(DateTime.Now));
 53             Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject("AAACCC\"VVV\" CF[] {}, \'\' FCVD"));
 54             Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(15));
 55             Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(false));
 56             Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(null));
 57 
 58             Console.WriteLine(JsonHelper.JsonSerialize(DateTime.Now));
 59             Console.WriteLine(JsonHelper.JsonSerialize("AAACCC\"VVV\" CF[] {}, \'\' FCVD"));
 60             Console.WriteLine(JsonHelper.JsonSerialize(15));
 61             Console.WriteLine(JsonHelper.JsonSerialize(false));
 62             Console.WriteLine(JsonHelper.JsonSerialize(null));
 63         }
 64         [Test]
 65         public void TestDeserializeMetaValue()
 66         {
 67             Console.WriteLine(Newtonsoft.Json.JsonConvert.DeserializeObject<DateTime>("\"2017-11-24T22:54:01.7724502+08:00\"")); //反序列化失败
 68             Console.WriteLine(Newtonsoft.Json.JsonConvert.DeserializeObject<string>("\"AAACCC\\\"VVV\\\" CF[] {}, \'\' FCVD\""));
 69             Console.WriteLine(Newtonsoft.Json.JsonConvert.DeserializeObject<int>("15"));
 70             Console.WriteLine(Newtonsoft.Json.JsonConvert.DeserializeObject<bool>("false"));
 71             //Console.WriteLine(Newtonsoft.Json.JsonConvert.DeserializeObject<object>(null));
 72 
 73             Console.WriteLine(JsonHelper.JsonDeserialize<DateTime>("\"2017-11-24T22:54:01.7724502+08:00\""));
 74             Console.WriteLine(JsonHelper.JsonDeserialize<string>("AAACCC\"VVV\" CF[] {}, \'\' FCVD"));
 75             Console.WriteLine(JsonHelper.JsonDeserialize<int>("15"));
 76             Console.WriteLine(JsonHelper.JsonDeserialize<bool>("false"));
 77             Console.WriteLine(JsonHelper.JsonDeserialize<object>(null));
 78         }
 79 
 80 
 81         [Test]
 82         public void TestDeserializeObject()
 83         {
 84             TestClass item = new TestClass();
 85             item.Name = "\\张三'\"'''AAB\r\nBCC\"\"\"";
 86             item.Age = 24;
 87             item.Birthday = new DateTime(1993, 04, 15, 10, 20, 35, 887);
 88             item.Money = 123456789012345678901234567890123456789f;
 89             item.Info = new TestClass {Name = "李四", Age = 22, Birthday = new DateTime(1995, 05, 20), Money = 1234};
 90 
 91             string webJson = SystemWebJson(item);
 92             Console.WriteLine(webJson);
 93             Console.WriteLine();
 94 
 95             string json = Newtonsoft.Json.JsonConvert.SerializeObject(item);
 96             Console.WriteLine(json);
 97             Console.WriteLine();
 98 
 99             JsonObject obj = null;
100             object reObj = null;
101             DateTime beginTime = DateTime.Now;
102             for (int i = 0; i < 100000; i++)
103             {
104                 obj = JsonHelper.JsonDeserializeObject(webJson);
105                 reObj = obj.ToObject(typeof(TestClass));
106             }
107             DateTime endTime = DateTime.Now;
108             Console.WriteLine(@"耗时: " + (endTime - beginTime).TotalMilliseconds);
109             Console.WriteLine(obj.ToJson());
110             Console.WriteLine(obj.ToString());
111             Console.WriteLine(reObj);
112         }
113         [Test]
114         public void TestDeserializeObject2()
115         {
116             TestClass item = new TestClass();
117             item.Name = "\\张三'\"'''AAB\r\nBCC\"\"\"";
118             item.Age = 24;
119             item.Birthday = new DateTime(1993, 04, 15, 10, 20, 35, 887);
120             item.Money = 123456789012345678901234567890123456789f;
121             item.Info = new TestClass { Name = "李四", Age = 22, Birthday = new DateTime(1995, 05, 20), Money = 1234 };
122 
123             string webJson = SystemWebJson(item);
124             Console.WriteLine(webJson);
125             Console.WriteLine();
126 
127             string json = Newtonsoft.Json.JsonConvert.SerializeObject(item);
128             Console.WriteLine(json);
129             Console.WriteLine();
130 
131 
132             object obj = null;
133             TestClass reObj = null;
134             DateTime beginTime = DateTime.Now;
135             for (int i = 0; i < 100000; i++)
136             {
137                 reObj = Newtonsoft.Json.JsonConvert.DeserializeObject<TestClass>(webJson);
138             }
139             DateTime endTime = DateTime.Now;
140             Console.WriteLine(@"耗时: " + (endTime - beginTime).TotalMilliseconds);
141             Console.WriteLine(reObj.Birthday.ToString("yyyy-MM-dd HH:mm:ss fffffff"));
142             Console.WriteLine(reObj);
143         }
144 
145 
146         [Test]
147         public void TestSerializeObject()
148         {
149             TestClass item = new TestClass();
150             item.Name = "\\张三'\"'''AAB\r\nBCC\"\"\"";
151             item.Age = 24;
152             item.Birthday = new DateTime(1993, 04, 15, 10, 20, 35, 887);
153             item.Money = 123456789012345678901234567890123456789f;
154             item.Info = new TestClass { Name = "李四", Age = 22, Birthday = new DateTime(1995, 05, 20), Money = 1234 };
155 
156             string json = null;
157             DateTime beginTime = DateTime.Now;
158             for (int i = 0; i < 100000; i++)
159             {
160                 json = JsonHelper.JsonSerialize(item);
161             }
162             DateTime endTime = DateTime.Now;
163             Console.WriteLine(@"耗时: " + (endTime - beginTime).TotalMilliseconds);
164             Console.WriteLine(json);
165         }
166         [Test]
167         public void TestSerializeObject2()
168         {
169             TestClass item = new TestClass();
170             item.Name = "\\张三'\"'''AAB\r\nBCC\"\"\"";
171             item.Age = 24;
172             item.Birthday = new DateTime(1993, 04, 15, 10, 20, 35, 887);
173             item.Money = 123456789012345678901234567890123456789f;
174             item.Info = new TestClass { Name = "李四", Age = 22, Birthday = new DateTime(1995, 05, 20), Money = 1234 };
175 
176             string json = null;
177             DateTime beginTime = DateTime.Now;
178             for (int i = 0; i < 100000; i++)
179             {
180                 json = Newtonsoft.Json.JsonConvert.SerializeObject(item);
181             }
182             DateTime endTime = DateTime.Now;
183             Console.WriteLine(@"耗时: " + (endTime - beginTime).TotalMilliseconds);
184             Console.WriteLine(json);
185         }
186 
187 
188 
189 
190 
191 
192 
193         [Test]
194         public void TestArray()
195         {
196             Console.WriteLine(typeof(string[]));
197             Console.WriteLine(Array.CreateInstance(typeof(string), 0));
198             Console.WriteLine(typeof(List<>).IsGenericTypeDefinition);  //true
199             Console.WriteLine(typeof(List<string>).IsGenericTypeDefinition);  //false
200             Console.WriteLine(typeof(IList<>).IsAssignableFrom(typeof(List<>)));
201             Console.WriteLine(typeof(IList<>).IsAssignableFrom(typeof(List<string>)));
202 
203             Console.WriteLine(typeof(IList).IsAssignableFrom(typeof(List<string>)));
204             Console.WriteLine(typeof(List<>).IsAssignableFrom(typeof(List<string>)));
205 
206             Console.WriteLine(typeof(IList).IsAssignableFrom(typeof(TestListClass)));  //true
207             Console.WriteLine(typeof(IList<>).IsAssignableFrom(typeof(TestListClass)));  //false
208 
209             Console.WriteLine(typeof(TestListClass).GetGenericArguments().Length);  //0
210             Console.WriteLine(JsonList.GetListElementType(typeof(TestListClass)));  //0
211             Console.WriteLine(typeof(string[]).GetElementType());  //0
212 
213 
214         }
215         [Test]
216         public void TestTimeStamp()
217         {
218             DateTime time = Convert.ToDateTime("1993-04-15T10:20:35.987654321");
219             long stamp = JsonHelper.DateTimeToStamp(time);
220             DateTime time2 = JsonHelper.StampToDateTime(stamp);
221 
222             Console.WriteLine(time.ToString("yyyy-MM-dd HH:mm:ss fffffff"));
223             Console.WriteLine(time2.ToString("yyyy-MM-dd HH:mm:ss fffffff"));
224         }
225         [Test]
226         public void TestStringReader()
227         {
228             StringReader reader = new StringReader(Resources.TestObjectJson2);
229 
230             int len = 0;
231             while (true)
232             {
233                 char c = (char)reader.Read();
234                 Console.Write(c);
235                 Console.Write((char)reader.Peek());
236                 len++;
237                 if (len >= 50000)
238                     break;
239             }
240         }
241 
242 
243 
244         private string SystemWebJson(object obj)
245         {
246             JavaScriptSerializer ser = new JavaScriptSerializer();
247             string json = ser.Serialize(obj);
248             return json;
249         }
250 
251 
252         public class TestClass
253         {
254             public string Name { get; set; }
255             public int Age { get; set; }
256             public DateTime Birthday { get; set; }
257             public TestClass Info { get; set; }
258             public float Money { get; set; }
259 
260         }
261         public class TestListClass : List<string>
262         {
263             
264         }
265 
266     }
267 
268 
269 
270 }
View Code

 

相关思考:

其实,不想用 Newtonsoft.Json.dll  的最大原因是:自己的框架 不想引用太多 第三方的东西,能完全独立最好。

而且,自己的一个框架 100KB,引用一个 400KB 的 Newtonsoft.Json.dll  —— 会让人觉得:你的框架70% 的功能都是 Newtonsoft.Json.dll  实现的,你只是做了个封装而已。

 

如何技能保证 框架的独立性,又能利用到 Newtonsoft.Json.dll  的性能呢?

方案如下:

> 启用 Emit 高速反射 (性能逼近 原生调用)

> 调用 JsonHelper 时,先尝试反射 Newtonsoft.Json.dll  是否存在,如果存在 就用 Emit 调用 Newtonsoft.Json.dll 

> 如果不存在,则使用 JsonHelper 的自带算法。

> 这样,似乎就能达到 想要的目的。

 

 

 

代码 1300行 就实现了 Json算法,但是 没啥技术含量 和 实用通用含量(可能小众用户用得到) —— 不敢发布到 博客园首页。

 

 

                                                                                                                                                                               InkFx

                                                                                                                                                                         2017-11-24 23:42

---------------------------------------------------------------------------------------------------------------------------------------------------

2018-08-08,将之前的 字符串解析算法 的核心函数,替换成了 新写的 栈结构字符串解析算法。

—— 性能直接逼近 Json.Net (Json.Net 之前测试的是 10W次 3.7秒, 之前的解析算法是 10W次 12秒 —— 这次的新算法是 4.2秒)

 

---------------------------------------------------------------------------------------------------------------------------------------------------

什么是 栈结构字符串:

> 具备嵌套逻辑的 字符串, Xml、Json、PDF的属性串  都属于 栈结构的字符串

> 这次,是因为 有这样一段 PDF属性串需要解析 —— 如果像之前的 JsonHelper 那样,写专用解析算法 特别废脑细胞【桌子一拍,劳资要写一个 通用栈结构字符串解析算法】。

 

Json 结构:

 1 {
 2 
 3    "age":52,
 4 
 5    "name":"Jim \u0027\u0027\u6211\u7231\u4f60\u000d\u000aABC |||| \u2A6D6 Carrey \"Love\" :[],{} AAA \'CCC\' ",
 6 
 7    "jsnFO":{
 8 
 9       "age":76,
10 
11       "name":"Morgan Freeman \"Love\" :[],{} AAA \'CCC\' ",
12 
13       "jsnSO":{
14 
15          "age":83,
16 
17          "name":"Clint Eastwood \"Love\" :[],{} AAA \'CCC\' ",
18 
19          "jsnTO":{
20 
21             "age":81,
22 
23             "name":"Michael Caine \"Love\" :[],{} AAA \'CCC\' ",
24 
25             "messages":[
26 
27                "You wouldn't hit a man..",
28 
29                "At this point, I'd set you..",
30 
31                "You know, your bobby dangler.."
32 
33             ]
34 
35          },
36 
37          "messages":[
38 
39             "This is the AK-47 assault..",
40 
41             "Are you feeling lucky.. \"Love\" :[],{} AAA \'CCC\' Are you feeling lucky.. \"Love\" :[],{} AAA \'CCC\' FCD",
42 
43             "When a naked man's chasing a.."
44 
45          ]
46 
47       },
48 
49       "messages":[
50 
51          "I once heard a wise man..",
52 
53          "Well, what is it today? More..",
54 
55          "Bruce... I'm God. Circumstances have.. \"Love\" :[],{} AAA \'CCC\' "
56 
57       ]
58 
59    },
60 
61    "messages":[
62 
63       "Hey, maybe I will give you a call.. \"Love\" :[],{} AAA \'CCC\' ",
64 
65       "Excuse me, I'd like to ask you a few..",
66 
67       "Brain freeze. Alrighty Then I just heard.."
68 
69    ]
70 
71 }

 

PDF属性串:

1 <</Type/Page/MediaBox [0 0 595 842]
2     /Rotate 0/Parent 3 0 R
3     /Resources<</ProcSet[/PDF /Text]
4     /ExtGState 14 0 R
5     /Font 15 0 R
6     >>
7     /Contents 5 0 R
8 >>
 1 <</Limits[(wl2)(wl48)]
 2 Names[(wl2) 337 0 R
 3 (wl20) 355 0 R
 4 (wl21) 356 0 R
 5 (wl22) 357 0 R
 6 (wl23) 358 0 R
 7 (wl24) 359 0 R
 8 (wl25) 360 0 R
 9 (wl26) 361 0 R
10 (wl27) 362 0 R
11 (wl28) 363 0 R
12 (wl29) 364 0 R
13 (wl3) 338 0 R
14 (wl30) 365 0 R
15 (wl31) 366 0 R
16 (wl32) 367 0 R
17 (wl33) 368 0 R
18 (wl34) 369 0 R
19 (wl35) 370 0 R
20 (wl36) 371 0 R
21 (wl37) 372 0 R
22 (wl38) 373 0 R
23 (wl39) 374 0 R
24 (wl4) 339 0 R
25 (wl40) 375 0 R
26 (wl41) 376 0 R
27 (wl42) 377 0 R
28 (wl43) 378 0 R
29 (wl44) 379 0 R
30 (wl45) 380 0 R
31 (wl46) 381 0 R
32 (wl47) 382 0 R
33 (wl48) 383 0 R
34 ]
35 >>

 

栈结构字符串解析算法 的 调用方式:

 1             //创建一个 栈结构字符串 解析方案
 2             StrStack stack = new StrStack();
 3             stack.RemoveEmptyAndLineEnd = true;
 4             stack.SetHasChildRule('{', '}', null);
 5             stack.SetHasChildRule('[', ']', null);
 6             stack.SetNoChildRule('"', '"', (l, i, c, s) => { return i <= 0 || l[i - 1] != '\\'; });
 7             stack.SetNoChildRule('\'', '\'', (l, i, c, s) => { return i <= 0 || l[i - 1] != '\\'; });
 8             stack.SetConstRule("null", null);
 9             stack.SetConstRule("true", null);
10             stack.SetConstRule("false", null);
11             stack.SetNumericRule();
12             stack.SetCharRule(';', null);
13             stack.SetCharRule(',', null);
14             stack.SetCharRule(':', null);
15 
16             //通过方案, 解析出所有 栈结构对象(包括嵌套逻辑)
17             List<StrStackObject> listItem = stack.Analyze(str);
18             StrStackObject item = listItem[0];
19 
20             //栈对象 和 嵌套逻辑有了, 接下来就是转换成 自己的 Json算法对象、 PDF算法对象了...

 

posted on 2017-11-24 23:46  InkFx  阅读(1777)  评论(1编辑  收藏  举报