背景:
> 一直使用 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 源码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Linq; namespace InkFx.Utils
{
/// <summary>
/// 不依赖 任何第三方JSON框架的 Json 辅助类
/// </summary>
public static class JsonHelper
{
#region 公 共 函 数 /// <summary>
/// 将指定对象转换成 JSON
/// </summary>
public static string JsonSerialize(object data)
{
return JsonSerialize(data, false);
}
/// <summary>
/// 将指定对象转换成 JSON
/// </summary>
public static string JsonSerialize(object data, bool throwEeception)
{
if (data == null) return "null"; try
{
JsonObject obj = ObjectToJsonObject(data);
return obj == null ? "null" : obj.ToJson();
}
catch (Exception exp)
{
if (throwEeception) throw;
else
{
string logMsg = "JsonHelper.JsonSerialize(object data) 序列化错误:" + exp;
Tools.LogError(logMsg, "Logs/Tools/ErrorLog/");
return null;
}
}
} /// <summary>
/// 将JSON 转换成 指定类型对象
/// </summary>
public static T JsonDeserialize<T>(string json)
{
return JsonDeserialize<T>(json, false);
}
/// <summary>
/// 将JSON 转换成 指定类型对象
/// </summary>
public static T JsonDeserialize<T>(string json, bool throwEeception)
{
if (IsNullOrWhiteSpace(json)) return default(T); try
{
JsonObject obj = StringToJsonObject(json);
T result = JsonObjectToObject<T>(obj);
return (T)result;
}
catch (Exception exp)
{
if (throwEeception) throw;
else
{
string logMsg = "JsonHelper.JsonDeserialize<T>(string json) 反序列化错误:" + exp;
Tools.LogError(logMsg, "Logs/Tools/ErrorLog/");
return default(T);
}
}
}
/// <summary>
/// 将JSON 转换成 指定类型对象
/// </summary>
public static object JsonDeserialize(string json, Type type)
{
return JsonDeserialize(json, type, false);
}
/// <summary>
/// 将JSON 转换成 指定类型对象
/// </summary>
public static object JsonDeserialize(string json, Type type, bool throwEeception)
{
if (IsNullOrWhiteSpace(json)) return null; try
{
JsonObject obj = StringToJsonObject(json);
object result = JsonObjectToObject(obj, type);
return result;
}
catch (Exception exp)
{
if (throwEeception) throw;
else
{
string logMsg = "JsonHelper.JsonDeserialize(string json, Type type) 反序列化错误:" + exp;
Tools.LogError(logMsg, "Logs/Tools/ErrorLog/");
return null;
}
}
} /// <summary>
/// 在 未指定 Json 反序列化类型 的情况下, 用 JsonObject 表达一个 Json对象
/// </summary>
public static JsonObject JsonDeserializeObject(string json)
{
return JsonDeserializeObject(json, false);
}
/// <summary>
/// 在 未指定 Json 反序列化类型 的情况下, 用 JsonObject 表达一个 Json对象
/// </summary>
public static JsonObject JsonDeserializeObject(string json, bool throwEeception)
{
if (IsNullOrWhiteSpace(json)) return null; try
{
JsonObject result = StringToJsonObject(json);
return result;
}
catch (Exception exp)
{
if (throwEeception) throw;
else
{
string logMsg = "JsonHelper.JsonDeserializeObject(string json) 反序列化错误:" + exp;
Tools.LogError(logMsg, "Logs/Tools/ErrorLog/");
return null;
}
}
}
/// <summary>
/// 在 未指定 Json 反序列化类型 的情况下, 用 字典、集合 表达一个 Json对象
/// </summary>
public static object JsonDeserializeHasnList(string json)
{
return JsonDeserializeHasnList<Hashtable>(json, false);
}
/// <summary>
/// 在 未指定 Json 反序列化类型 的情况下, 用 字典、集合 表达一个 Json对象
/// </summary>
public static object JsonDeserializeHasnList(string json, bool throwEeception)
{
return JsonDeserializeHasnList<Hashtable>(json, throwEeception);
}
/// <summary>
/// 在 未指定 Json 反序列化类型 的情况下, 用 字典、集合 表达一个 Json对象
/// </summary>
public static object JsonDeserializeHasnList<HashT>(string json) where HashT : IDictionary, new()
{
return JsonDeserializeHasnList<HashT>(json, false);
}
/// <summary>
/// 在 未指定 Json 反序列化类型 的情况下, 用 字典、集合 表达一个 Json对象
/// </summary>
public static object JsonDeserializeHasnList<HashT>(string json, bool throwEeception) where HashT : IDictionary, new()
{
if (IsNullOrWhiteSpace(json)) return null; try
{
JsonObject obj = StringToJsonObject(json);
object result = obj.ToHashList<HashT>();
return result;
}
catch (Exception exp)
{
if (throwEeception) throw;
else
{
string logMsg = "JsonHelper.JsonDeserializeHasnList(string json) 反序列化错误:" + exp;
Tools.LogError(logMsg, "Logs/Tools/ErrorLog/");
return null;
}
}
} /// <summary>
/// 将 JsonObject 实体 分析成 指定的类型
/// </summary>
public static T JsonObjectToObject<T>(JsonObject obj)
{
if (obj == null) return default(T);
object result = JsonObjectToObject(obj, typeof (T));
return (T)result;
}
/// <summary>
/// 将 JsonObject 实体 分析成 指定的类型
/// </summary>
public static object JsonObjectToObject(JsonObject obj, Type type)
{
if (obj == null) return null;
return obj.ToObject(type);
} #endregion #region 私 有 函 数 private static DateTime m_StampRoot = new DateTime(, , , , , , , DateTimeKind.Utc);
private static readonly Regex m_RegNum = new Regex(@"\d+", RegexOptions.Compiled | RegexOptions.IgnoreCase); /// <summary>
/// Json时间戳 转 时间
/// </summary>
public static DateTime StampToDateTime(string timeStamp)
{
Match match = m_RegNum.Match(timeStamp);
if (!match.Success) return m_StampRoot;
long num = long.Parse(match.Value);
return StampToDateTime(num);
}
/// <summary>
/// Json时间戳 转 时间
/// </summary>
public static DateTime StampToDateTime(long timeStamp)
{
return m_StampRoot.AddMilliseconds(timeStamp).ToLocalTime();
}
/// <summary>
/// 时间 转 Json时间戳
/// </summary>
public static long DateTimeToStamp(DateTime time)
{
return (long)(time.ToUniversalTime() - m_StampRoot).TotalMilliseconds;
} private static bool IsNullOrWhiteSpace(string value)
{
if (value == null) return true;
for (int i = ; i < value.Length; i++)
if (!char.IsWhiteSpace(value[i]))
return false;
return true;
} #endregion #region 核 心 算 法 private static JsonObject ObjectToJsonObject(object data)
{
if (data == null) return null; Type type = data.GetType(); if (ReflectHelper.IsMetaType(type))
{
return new JsonValue(data, false);
}
else if (data is IDictionary)
{
JsonHash jsonHash = new JsonHash();
IDictionary hash = (IDictionary) data;
foreach (object key in hash.Keys)
{
object value = hash[key];
JsonObject jsonV = ObjectToJsonObject(value);
jsonHash[key.ToString()] = jsonV;
}
return jsonHash;
}
else if (data is IList)
{
JsonList jsonList = new JsonList();
foreach (object item in (IList)data)
{
JsonObject jsonObj = ObjectToJsonObject(item);
if (jsonObj != null) jsonList.Add(jsonObj);
}
return jsonList;
}
else
{
Hashtable hash = new Hashtable();
FieldInfo[] listField = type.GetFields();
PropertyInfo[] listProp = type.GetProperties();
foreach (FieldInfo field in listField)
{
object fieldObj = ReflectHelper.GetValue(data, field);
hash[field.Name] = fieldObj;
}
foreach (PropertyInfo prop in listProp)
{
object propObj = ReflectHelper.GetValue(data, prop);
hash[prop.Name] = propObj;
}
return ObjectToJsonObject(hash);
}
}
private static JsonObject StringToJsonObject(string json)
{
List<JsonObject> queue = new List<JsonObject>();
using (JsonReader reader = new JsonReader(json))
{
while (!reader.IsEnd)
{
string item = reader.Read();
if (string.IsNullOrEmpty(item)) continue;
if (item.Length == )
{
char @char = item[];
if (@char == ARRAY_BEGIN)
{
queue.Add(new JsonList());
}
else if (@char == OBJECT_BEGIN)
{
queue.Add(new JsonHash());
}
else if (@char == ITEM_SPLIT)
{
MergeLastJsonKeyValue(queue);
}
else if (@char == KV_SPLIT)
{
MergeLastJsonKeyValue(queue);
queue.Add(new JsonKeyValue());
}
else if (@char == ARRAY_END)
{
MergeLastJsonKeyValue(queue); #region 搜索最近的一个数组开始 int index = queue.FindLastIndex(x => x.IsList);
JsonList array = (JsonList)queue[index];
for (int i = index + , count = queue.Count; i < count; i++) array.Add(queue[i]);
queue.RemoveRange(index + , queue.Count - index - ); #endregion
}
else if (@char == OBJECT_END)
{
MergeLastJsonKeyValue(queue); #region 搜索最近的一个对象开始 int index = queue.FindLastIndex(x => x.IsHash);
JsonHash hash = (JsonHash)queue[index];
List<JsonObject> list = new List<JsonObject>();
for (int i = index + , count = queue.Count; i < count; i++) list.Add(queue[i]);
List<JsonObject> listKV = list.FindAll(x => (x is JsonKeyValue)); for (int i = , count = listKV.Count; i < count; i++)
{
JsonKeyValue keyValue = (JsonKeyValue)listKV[i];
hash.Hash[keyValue.Key.Value.ToString()] = keyValue.Value;
}
queue.RemoveRange(index + , queue.Count - index - ); #endregion
}
}
else
{
queue.Add(new JsonValue(item, true));
}
}
reader.Dispose();
} int queueCount = queue.Count;
if (queueCount == ) return queue[];
if (queueCount >= )
{
JsonList jsonList = new JsonList();
foreach (JsonObject item in queue) jsonList.Add(item);
return jsonList;
} return null;
}
private static void MergeLastJsonKeyValue(List<JsonObject> queue)
{
if (queue == null || queue.Count <= ) return;
int count = queue.Count; if (queue[count - ] is JsonKeyValue)
{
//标准情况
JsonObject key = queue[count - ];
if (!(key is JsonValue)) return;
JsonObject value = queue[count - ];
JsonKeyValue keyValue = (JsonKeyValue)queue[count - ];
keyValue.Key = (JsonValue)key;
keyValue.Value = value;
queue.RemoveAt(count - );
queue.RemoveAt(count - );
}
else if (queue[count - ] is JsonKeyValue)
{
//有键无值
JsonObject key = queue[count - ];
if (!(key is JsonValue)) return;
JsonKeyValue keyValue = (JsonKeyValue)queue[count - ];
keyValue.Key = (JsonValue)key;
queue.RemoveAt(count - );
} } private const int ARRAY_BEGIN = '[';
private const int ARRAY_END = ']';
private const int OBJECT_BEGIN = '{';
private const int OBJECT_END = '}';
private const int ITEM_SPLIT = ',';
private const int KV_SPLIT = ':';
private const int STR_APOS = '\'';
private const int STR_QUOT = '"';
private const int STR_ESCAPE = '\\';
private const int CHAR_SPACE = (int)' ';
private const int CHAR_R = (int)'\r';
private const int CHAR_N = (int)'\n';
private const int CHAR_T = (int)'\t';
private const int CHAR_A = (int)'\a';
private const int CHAR_B = (int)'\b';
private const int CHAR_F = (int)'\f';
private const int CHAR_V = (int)'\v';
private const int CHAR_0 = (int)'\0'; private class JsonReader : IDisposable
{
public JsonReader(string json)
{
//Json = FormatString(json);
Json = json;
Length = Json == null ? : Json.Length;
} private string Json = string.Empty;
private int Position = ;
private int Length = ;
internal bool IsEnd = false; /// <summary>
/// 读取一个JSON的完整节点 字符串, 返回值可能有 [ ] { } , : String
/// </summary>
/// <returns></returns>
public string Read()
{
if (Length <= || Position >= Length) return string.Empty; StringBuilder sb = new StringBuilder();
bool isApos = false, isQuot = false; int len = ;
while (Position <= Length)
{
int p = Position;
char @char = Json[p];
int @charv = (int)@char;
Position++; IsEnd = Position >= Length; if (char.IsWhiteSpace(@char))
{
if (/*sb.Length <= 0*/len <= ) { continue; }
if (@charv != CHAR_SPACE && @charv != CHAR_R && @charv != CHAR_N && @charv != CHAR_T) { continue; } //转义符 仅保留 空格 \r \n \t
} sb.Append(@char); len++; int @pcharv = (int)((p - >= ) ? Json[p - ] : char.MinValue);
if (!isApos && !isQuot) { if (@charv == STR_APOS && @pcharv != STR_ESCAPE) { isApos = true; } else if (@charv == STR_QUOT && @pcharv != STR_ESCAPE) { isQuot = true; } }
else if ((isApos || isQuot) && /*sb.Length > 1*/ len > )
{
if (isApos && @charv == STR_APOS && @pcharv != STR_ESCAPE) { isApos = false; }
else if (isQuot && @charv == STR_QUOT && @pcharv != STR_ESCAPE) { isQuot = false; }
} if (!isApos && !isQuot)
{
if (IsConstChar(@charv)) break;
if (p + < Length) { char @nchar = Json[p + ]; if (IsConstChar((int)@nchar)) break; }
}
} return sb.ToString().Trim();
} private static bool IsConstChar(int @charv)
{
return (@charv == ARRAY_BEGIN || @charv == ARRAY_END || @charv == OBJECT_BEGIN || @charv == OBJECT_END || @charv == ITEM_SPLIT || @charv == KV_SPLIT);
}
public void Dispose()
{
Json = null;
Position = Length = ;
}
} #endregion } #region Json 实 体 public abstract class JsonObject
{
public bool IsValue { get { return this is JsonValue; } }
public bool IsList { get { return this is JsonList; } }
public bool IsHash { get { return this is JsonHash; } }
public bool IsKeyValue { get { return this is JsonKeyValue; } } public virtual string ToJson()
{
return ToJson(, false);
}
public virtual string ToJson(int level)
{
return ToJson(level, false);
}
public abstract string ToJson(int level, bool format); public abstract object ToObject(Type type);
public object ToHashList()
{
return InnerToHashList<Dictionary<string, object>>();
}
public object ToHashList<HashT>() where HashT : IDictionary, new()
{
return InnerToHashList<HashT>();
}
protected abstract object InnerToHashList<HashT>() where HashT : IDictionary, new(); public override string ToString()
{
return ToJson(, true);
}
}
public class JsonValue : JsonObject
{
public JsonValue() { }
public JsonValue(object value) : this(value, false)
{
}
public JsonValue(object value, bool json)
{
this.m_Value = FmtValue(value, json);
} private object m_Value = null; public string Json
{
get
{
object value = m_Value;
//理论上这两行代码 不可达, 理论上 m_Value 不可能是 Json对象
if (value is JsonValue) return ((JsonValue)value).Json;
if (value is JsonObject) return ((JsonObject)value).ToJson(); if (m_Value == null) return "null";
if (m_Value is bool) return ((bool)m_Value).ToString().ToLower();
if (m_Value is Guid) return "\"" + ((Guid)m_Value).ToString("D") + "\"";
if (m_Value is DateTime) return "\"" + ((DateTime)m_Value).ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "\"";
if (m_Value is StringBuilder || m_Value is string || m_Value is char) return "\"" + StringToJsonString(m_Value.ToString()) + "\"";
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();
if (m_Value is float || m_Value is double || m_Value is decimal) return m_Value.ToString(); //if (m_Value is float) return ((float)m_Value).ToString();
//if (m_Value is double) return ((double)m_Value).ToString();
//if (m_Value is decimal) return ((decimal)m_Value).ToString(); return "\"" + StringToJsonString(m_Value.ToString()) + "\"";
}
}
public object Value
{
get { return m_Value; }
set { this.m_Value = FmtValue(value, false); }
} private static object FmtValue(object value, bool json)
{
if (value == null) { return null; }
if (value is bool) { return (bool)value; }
if (value is Guid) { return (Guid)value; }
if (value is DateTime) { return (DateTime)value; }
if (value is StringBuilder || value is string || value is char)
{
string temp = value.ToString();
int len = temp.Length;
if (json && len >= && temp[] == '"' && temp[len - ] == '"')
{
string str = JsonStringToString(temp.Substring(, len - ));
DateTime time; if (TryToDateTime(str, out time)) return time;
return str;
}
else if (json && len >= && temp[] == '\'' && temp[len - ] == '\'')
{
string str = JsonStringToString(temp.Substring(, len - ));
DateTime time; if (TryToDateTime(str, out time)) return time;
return str;
}
else
{
if (json)
{
//bool float 不需要引号
string trim = temp.Trim();
string lower = trim.ToLower();
if (lower == "null") return null;
if (lower == "true") return true;
if (lower == "false") return false;
if (lower.StartsWith("new ")) return trim;
DateTime time; if (TryToDateTime(lower, out time)) return time;
double doub; if (double.TryParse(trim, out doub)) return doub;
} return temp;
}
}
return value;
}
private static bool TryToDateTime(string source, out DateTime time)
{
try
{
string lower = source.ToLower();
if (lower.StartsWith("/date(") || lower.StartsWith("date(") || lower.StartsWith("\\/date("))
{
//兼容微软最初的 Json时间格式 "Birthday":"\/Date(734840435887)\/"
time = JsonHelper.StampToDateTime(lower);
return (time != DateTime.MinValue);
}
}
catch (Exception) { }
time = DateTime.MinValue;
return false;
} public override object ToObject(Type type)
{
if (type == null || type == typeof (object)) return Value;
return ReflectHelper.ChangeType(Value, type);
}
public override string ToJson(int level, bool format)
{
//return new string(' ', level*2) + Value;
return Json;
}
protected override object InnerToHashList<HashT>()
{
if (Value == null) return null;
if (Value is JsonObject) return ((JsonObject)Value).ToHashList<HashT>();
return Value;
} private static string JsonStringToString(string json)
{
if (string.IsNullOrEmpty(json)) return string.Empty;
StringBuilder sb = new StringBuilder();
for (int i = , c = json.Length; i < c; i++)
{
char @char = json[i];
if (@char != '\\') { sb.Append(@char); continue; }
if (i + >= c) { sb.Append(@char); continue; }
char @charn = json[i + ];
if (@charn == '\\') { sb.Append('\\'); i++; continue; }
if (@charn == 'r') { sb.Append('\r'); i++; continue; }
if (@charn == 'n') { sb.Append('\n'); i++; continue; }
if (@charn == 't') { sb.Append('\t'); i++; continue; }
if (@charn == 'a') { sb.Append('\a'); i++; continue; }
if (@charn == 'b') { sb.Append('\b'); i++; continue; }
if (@charn == 'f') { sb.Append('\f'); i++; continue; }
if (@charn == 'v') { sb.Append('\v'); i++; continue; }
if (@charn == '"') { sb.Append('"'); i++; continue; }
if (@charn == '\'') { sb.Append('\''); i++; continue; }
if (@charn == '') { /*sb.Append('\0');*/ i++; continue; } // \0字符直接排除 if (@charn == 'u')
{
//\uFFFF 一是 Unicode 字符, 这类字符 一般是 4位 \uFFFF, 但是理论上 可以有5位 \uFFFFF
string hex = json.Substring(i + , );
//char h5 = json[i + 2 + 4];
//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');
//if (isHex5) hex = hex + h5;
int num;
if (int.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out num))
{
sb.Append((char)num); i = i + ; /*if (isHex5){i++;} */continue;
}
else { sb.Append("\\u"); i++; continue; }
}
}
return sb.ToString();
}
internal static string StringToJsonString(string str)
{
if (string.IsNullOrEmpty(str)) return string.Empty; StringBuilder sb = new StringBuilder();
for (int i = , c = str.Length; i < c; i++)
{
char @char = str[i];
//if (@char == '\'') { sb.Append("\\'"); continue; } //单引号不再进行转义
if (@char == '"') { sb.Append("\\\""); continue; }
if (@char == '\\') { sb.Append("\\\\"); continue; }
if (@char == '\r') { sb.Append("\\r"); continue; }
if (@char == '\n') { sb.Append("\\n"); continue; }
if (@char == '\t') { sb.Append("\\t"); continue; }
if (@char == '\a') { sb.Append("\\a"); continue; }
if (@char == '\b') { sb.Append("\\b"); continue; }
if (@char == '\f') { sb.Append("\\f"); continue; }
if (@char == '\v') { sb.Append("\\v"); continue; }
if (@char == '\0') { /*sb.Append('\\\0');*/ continue; } // \0字符直接排除
sb.Append(@char);
}
return sb.ToString();
}
}
public class JsonKeyValue : JsonObject
{
public JsonKeyValue() { }
public JsonKeyValue(JsonValue key, JsonObject value) { this.Key = key; this.Value = value; } public JsonValue Key { get; set; }
public JsonObject Value { get; set; } public override object ToObject(Type type)
{
object obj = Activator.CreateInstance(type); ReflectHelper.SetValue(obj, "Key", (Key == null ? string.Empty : Key.Value.ToString())); Type propOrFieldType = ReflectHelper.GetPropertyOrFieldType(type, "Value");
object value = (Value == null ? null : Value.ToObject(propOrFieldType));
ReflectHelper.SetValue(obj, "Value", value); return obj;
}
public override string ToJson(int level, bool format)
{
return string.Format((format ? @"{0}: {1}" : @"{0}:{1}"), (Key == null ? string.Empty : Key.ToJson(, false)), (Value == null ? "null" : Value.ToJson(level, format)));
}
public new KeyValuePair<string, object> ToHashList()
{
return (KeyValuePair<string, object>)InnerToHashList<Dictionary<string, object>>();
}
public new KeyValuePair<string, object> ToHashList<HashT>() where HashT : IDictionary, new()
{
return (KeyValuePair<string, object>)InnerToHashList<HashT>();
}
protected override object InnerToHashList<HashT>()
{
return new KeyValuePair<string, object>((Key == null ? string.Empty : Key.Value.ToString()), (Value == null ? null : Value.ToHashList<HashT>()));
}
}
public class JsonList : JsonObject, IList, IList<JsonObject>
{
public bool HasValues { get; set; } [NonSerialized]
private List<JsonObject> m_List;
private List<JsonObject> List
{
get { return m_List ?? (m_List = new List<JsonObject>()); }
} public int Count
{
get { return this.List.Count; }
}
public JsonObject this[int index]
{
get { return this.List[index]; }
set { this.List[index] = value; }
}
public void Add(JsonObject item)
{
this.List.Add(item);
}
public void Insert(int index, JsonObject item)
{
this.List.Insert(index, item);
}
public void Remove(JsonObject item)
{
this.List.Remove(item);
}
public void RemoveAt(int index)
{
this.List.RemoveAt(index);
}
public void Clear()
{
this.List.Clear();
}
public bool Contains(JsonObject item)
{
return this.List.Contains(item);
}
public int IndexOf(JsonObject item)
{
return this.List.IndexOf(item);
}
public void CopyTo(JsonObject[] array, int arrayIndex)
{
this.List.CopyTo(array, arrayIndex);
} public override object ToObject(Type type)
{
if (m_List == null) return null; Type listType = null;
Type itemType = null;
int sign = ;
if (type.IsArray) { listType = type; itemType = listType.GetElementType(); sign = ; }
else if (typeof(IList<>).IsAssignableFrom(type)) { listType = type; itemType = GetListElementType(listType); sign = ; }
else if (typeof(IList).IsAssignableFrom(type)) { listType = type; itemType = typeof(object); sign = ; }
else { listType = typeof(List<>).MakeGenericType(type); itemType = type; sign = ; } if (sign < || listType == null || ((sign == || sign == ) && listType.IsGenericTypeDefinition))
throw new Exception(string.Format("JsonList 无法反序列化得到类型: {0}", type.FullName)); int count = (m_List != null) ? m_List.Count : ;
if (sign == || sign == || sign == )
{
IList list = (IList)Activator.CreateInstance(listType);
if (count >= )
foreach (JsonObject item in m_List)
{
object obj = item.ToObject(itemType);
list.Add(obj);
}
return list;
}
else if (sign == )
{
Array array = Array.CreateInstance(itemType, count);
if (count >= )
for (int i = ; i < count; i++)
{
JsonObject item = m_List[i];
object obj = item.ToObject(itemType);
array.SetValue(obj, i);
}
return array;
} return null;
}
public override string ToJson(int level, bool format)
{
string rn = !format ? string.Empty : "\r\n";
string prev = !format ? string.Empty : new string(' ', (level) * );
string prev2 = !format ? string.Empty : new string(' ', (level + ) * );
StringBuilder sb = new StringBuilder();
sb.Append("[" + rn);
if (m_List != null)
{
List<string> list = new List<string>();
foreach (JsonObject item in m_List)
list.Add(prev2 + item.ToJson(level + , format)); for (int i = , count = list.Count; i < count; i++)
sb.Append(list[i] + (i == count - ? string.Empty : ",") + rn);
}
sb.Append(prev + "]");
return sb.ToString();
}
public new List<object> ToHashList()
{
return (List<object>)InnerToHashList<Dictionary<string, object>>();
}
public new List<object> ToHashList<HashT>() where HashT : IDictionary, new()
{
return (List<object>)InnerToHashList<HashT>();
}
protected override object InnerToHashList<HashT>()
{
if (m_List == null) return null; List<object> list = new List<object>();
foreach (JsonObject item in m_List)
list.Add(item.ToHashList<HashT>());
return list;
} /// <summary>
/// 查找指定 List类型, 对应的 集合成员类型
/// </summary>
public static Type GetListElementType(Type listType)
{
Type baseType = listType;
Type[] itfsTypes = baseType.GetInterfaces();
foreach (Type itfsType in itfsTypes)
{
if (itfsType.IsGenericType && !itfsType.IsGenericTypeDefinition && typeof(IList<>) == itfsType.GetGenericTypeDefinition())
{
Type[] genericTypes = itfsType.GetGenericArguments();
if (genericTypes.Length == ) return genericTypes[];
}
} foreach (Type itfsType in itfsTypes)
{
if (itfsType.IsGenericType && !itfsType.IsGenericTypeDefinition && typeof(ICollection<>) == itfsType.GetGenericTypeDefinition())
{
Type[] genericTypes = itfsType.GetGenericArguments();
if (genericTypes.Length == ) return genericTypes[];
}
} if (typeof(IList).IsAssignableFrom(listType)) { return typeof(object); }
return null;
} #region 中转的继承 IEnumerator<JsonObject> IEnumerable<JsonObject>.GetEnumerator()
{
return ((IEnumerable<JsonObject>)this.List).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)this.List).GetEnumerator();
}
void ICollection.CopyTo(Array array, int index)
{
((ICollection)this.List).CopyTo(array, index);
}
bool ICollection<JsonObject>.Remove(JsonObject item)
{
return ((ICollection<JsonObject>)this.List).Remove(item);
}
int ICollection<JsonObject>.Count
{
get { return ((ICollection<JsonObject>)this.List).Count; }
}
bool ICollection<JsonObject>.IsReadOnly
{
get { return ((ICollection<JsonObject>)this.List).IsReadOnly; }
}
int ICollection.Count
{
get { return ((ICollection)this.List).Count; }
}
object ICollection.SyncRoot
{
get { return ((ICollection)this.List).SyncRoot; }
}
bool ICollection.IsSynchronized
{
get { return ((ICollection)this.List).IsSynchronized; }
}
int IList.Add(object value)
{
return ((IList)this.List).Add(value);
}
bool IList.Contains(object value)
{
return ((IList)this.List).Contains(value);
}
void ICollection<JsonObject>.Add(JsonObject item)
{
((ICollection<JsonObject>)this.List).Add(item);
}
void ICollection<JsonObject>.Clear()
{
((ICollection<JsonObject>)this.List).Clear();
}
bool ICollection<JsonObject>.Contains(JsonObject item)
{
return ((ICollection<JsonObject>)this.List).Contains(item);
}
void ICollection<JsonObject>.CopyTo(JsonObject[] array, int arrayIndex)
{
((ICollection<JsonObject>)this.List).CopyTo(array, arrayIndex);
}
void IList.Clear()
{
((IList)this.List).Clear();
}
int IList.IndexOf(object value)
{
return ((IList)this.List).IndexOf(value);
}
void IList.Insert(int index, object value)
{
((IList)this.List).Insert(index, value);
}
void IList.Remove(object value)
{
((IList)this.List).Remove(value);
}
int IList<JsonObject>.IndexOf(JsonObject item)
{
return ((IList<JsonObject>)this.List).IndexOf(item);
}
void IList<JsonObject>.Insert(int index, JsonObject item)
{
((IList<JsonObject>)this.List).Insert(index, item);
}
void IList<JsonObject>.RemoveAt(int index)
{
((IList<JsonObject>)this.List).RemoveAt(index);
}
JsonObject IList<JsonObject>.this[int index]
{
get { return ((IList<JsonObject>)this.List)[index]; }
set { ((IList<JsonObject>)this.List)[index] = value; }
}
void IList.RemoveAt(int index)
{
((IList)this.List).RemoveAt(index);
}
object IList.this[int index]
{
get { return ((IList)this.List)[index]; }
set { ((IList)this.List)[index]=value; }
}
bool IList.IsReadOnly
{
get { return ((IList)this.List).IsReadOnly; }
}
bool IList.IsFixedSize
{
get { return ((IList)this.List).IsFixedSize; }
} #endregion
}
public class JsonHash : JsonObject, IDictionary, IDictionary<string, JsonObject>
{
public bool HasValues { get; set; } [NonSerialized]
private Dictionary<string, JsonObject> m_Hash;
public Dictionary<string, JsonObject> Hash
{
get { return m_Hash ?? (m_Hash = new Dictionary<string, JsonObject>()); }
} public JsonObject this[string key]
{
get
{
if (m_Hash == null || m_Hash.Count <= ) return null;
JsonObject value;
if (m_Hash.TryGetValue(key, out value)) return value;
return null;
}
set
{
if (key == null) return;
if (!this.Hash.ContainsKey(key)) this.Hash.Add(key, value);
else this.Hash[key] = value;
}
}
public int Count
{
get { return this.Hash.Count; }
}
public void Add(string key, JsonObject value)
{
this.Hash.Add(key, value);
}
public void Remove(string key)
{
this.Hash.Remove(key);
}
public void Clear()
{
this.Hash.Clear();
}
public bool ContainsKey(string key)
{
return this.Hash.ContainsKey(key);
}
public bool TryGetValue(string key, out JsonObject value)
{
return this.Hash.TryGetValue(key, out value);
}
public ICollection<string> Keys
{
get { return this.Hash.Keys; }
}
public ICollection<JsonObject> Values
{
get { return this.Hash.Values; }
} public override object ToObject(Type type)
{
if (m_Hash == null) return null; int sign = ;
if (type == null || type == typeof(object) || typeof(IDictionary).IsAssignableFrom(type)) { if (type == null || type == typeof(object)) { type = typeof(Hashtable); } sign = ; }
else { sign = ; } if (sign < || (sign == && type.IsGenericTypeDefinition))
throw new Exception(string.Format("JsonHash 无法反序列化得到类型: {0}", type.FullName)); int count = (m_Hash != null) ? m_Hash.Count : ;
if (sign == )
{
IDictionary hash = (IDictionary)Activator.CreateInstance(type);
if (count >= )
foreach (KeyValuePair<string, JsonObject> pair in m_Hash)
{
object obj = pair.Value.ToObject(typeof(object));
if (hash.Contains(pair.Key)) hash[pair.Key] = obj;
else hash.Add(pair.Key, obj);
}
return hash;
}
else if (sign == )
{
object hash = Activator.CreateInstance(type);
if (count >= )
foreach (KeyValuePair<string, JsonObject> pair in m_Hash)
{
string key = pair.Key;
Type propOrFieldType = ReflectHelper.GetPropertyOrFieldType(type, key);
object value = (pair.Value == null ? null : pair.Value.ToObject(propOrFieldType));
ReflectHelper.SetValue(hash, key, value);
}
return hash;
} return null;
} public override string ToJson(int level, bool format)
{
string rn = !format ? string.Empty : "\r\n";
string prev = !format ? string.Empty : new string(' ', (level) * );
string prev2 = !format ? string.Empty : new string(' ', (level + ) * );
StringBuilder sb = new StringBuilder();
sb.Append("{" + rn);
if (m_Hash != null)
{
List<string> list = new List<string>();
foreach (KeyValuePair<string, JsonObject> pair in m_Hash)
list.Add(prev2 + string.Format((format ? @"""{0}"": {1}" : @"""{0}"":{1}"), (pair.Key ?? string.Empty), (pair.Value == null ? "null" : pair.Value.ToJson(level + , format)))); for (int i = , count = list.Count; i < count; i++)
sb.Append(list[i] + (i == count - ? string.Empty : ",") + rn);
}
sb.Append(prev + "}");
return sb.ToString();
}
public new Dictionary<string, object> ToHashList()
{
return (Dictionary<string, object>)InnerToHashList<Dictionary<string, object>>();
}
public new HashT ToHashList<HashT>() where HashT : IDictionary, new()
{
return (HashT)InnerToHashList<HashT>();
}
protected override object InnerToHashList<HashT>()
{
if (m_Hash == null) return null; HashT hash = new HashT();
foreach (KeyValuePair<string, JsonObject> pair in m_Hash)
{
if (hash.Contains(pair.Key)) hash[pair.Key] = pair.Value.ToHashList<HashT>();
else hash.Add(pair.Key, pair.Value.ToHashList<HashT>());
}
return hash;
} #region 中转的继承 bool IDictionary.Contains(object key)
{
return ((IDictionary)this.Hash).Contains(key);
}
void IDictionary.Add(object key, object value)
{
((IDictionary)this.Hash).Add(key, value);
}
void ICollection<KeyValuePair<string, JsonObject>>.Add(KeyValuePair<string, JsonObject> item)
{
((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).Add(item);
}
void ICollection<KeyValuePair<string, JsonObject>>.Clear()
{
((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).Clear();
}
bool ICollection<KeyValuePair<string, JsonObject>>.Contains(KeyValuePair<string, JsonObject> item)
{
return ((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).Contains(item);
}
void ICollection<KeyValuePair<string, JsonObject>>.CopyTo(KeyValuePair<string, JsonObject>[] array, int arrayIndex)
{
((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).CopyTo(array, arrayIndex);
}
bool ICollection<KeyValuePair<string, JsonObject>>.Remove(KeyValuePair<string, JsonObject> item)
{
return ((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).Remove(item);
}
int ICollection<KeyValuePair<string, JsonObject>>.Count
{
get { return ((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).Count; }
}
bool ICollection<KeyValuePair<string, JsonObject>>.IsReadOnly
{
get { return ((ICollection<KeyValuePair<string, JsonObject>>)this.Hash).IsReadOnly; }
}
void IDictionary.Clear()
{
((IDictionary)this.Hash).Clear();
}
IEnumerator<KeyValuePair<string, JsonObject>> IEnumerable<KeyValuePair<string, JsonObject>>.GetEnumerator()
{
return ((IEnumerable<KeyValuePair<string, JsonObject>>)this.Hash).GetEnumerator();
}
IDictionaryEnumerator IDictionary.GetEnumerator()
{
return ((IDictionary)this.Hash).GetEnumerator();
}
void IDictionary.Remove(object key)
{
((IDictionary)this.Hash).Remove(key);
}
object IDictionary.this[object key]
{
get { return ((IDictionary)this.Hash)[key]; }
set { ((IDictionary)this.Hash)[key] = value; }
}
bool IDictionary<string, JsonObject>.ContainsKey(string key)
{
return ((IDictionary<string, JsonObject>)this.Hash).ContainsKey(key);
}
void IDictionary<string, JsonObject>.Add(string key, JsonObject value)
{
((IDictionary<string, JsonObject>)this.Hash).Add(key, value);
}
bool IDictionary<string, JsonObject>.Remove(string key)
{
return ((IDictionary<string, JsonObject>)this.Hash).Remove(key);
}
bool IDictionary<string, JsonObject>.TryGetValue(string key, out JsonObject value)
{
return ((IDictionary<string, JsonObject>)this.Hash).TryGetValue(key, out value);
}
JsonObject IDictionary<string, JsonObject>.this[string key]
{
get { return ((IDictionary<string, JsonObject>)this.Hash)[key]; }
set { ((IDictionary<string, JsonObject>)this.Hash)[key] = value; }
}
ICollection IDictionary.Keys
{
get { return ((IDictionary)this.Hash).Keys; }
}
ICollection<JsonObject> IDictionary<string, JsonObject>.Values
{
get { return ((IDictionary<string, JsonObject>)this.Hash).Values; }
}
ICollection<string> IDictionary<string, JsonObject>.Keys
{
get { return ((IDictionary<string, JsonObject>)this.Hash).Keys; }
}
ICollection IDictionary.Values
{
get { return ((IDictionary)this.Hash).Values; }
}
bool IDictionary.IsReadOnly
{
get { return ((IDictionary)this.Hash).IsReadOnly; }
}
bool IDictionary.IsFixedSize
{
get { return ((IDictionary)this.Hash).IsFixedSize; }
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)this.Hash).GetEnumerator();
}
void ICollection.CopyTo(Array array, int index)
{
((ICollection)this.Hash).CopyTo(array, index);
}
int ICollection.Count
{
get { return ((ICollection)this.Hash).Count; }
}
object ICollection.SyncRoot
{
get { return ((ICollection)this.Hash).SyncRoot; }
}
bool ICollection.IsSynchronized
{
get { return ((ICollection)this.Hash).IsSynchronized; }
} #endregion
} #endregion
}
JsonHelper_Test 源码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.Script.Serialization;
using InkFx.Utils.Test.Properties;
using NUnit.Framework; namespace InkFx.Utils.Test
{
public class Test_JsonHelper
{
[Test]
public void TestDeserialize()
{
string json = Resources.TestObjectJson2.Trim(); JsonObject jsonObj = JsonHelper.JsonDeserializeObject(json);
DateTime beginTime = DateTime.Now;
for (int i = ; i < ; i++)
{
jsonObj = JsonHelper.JsonDeserializeObject(json);
}
DateTime endTime = DateTime.Now;
Console.WriteLine(@"耗时: " + (endTime - beginTime).TotalMilliseconds);
Console.WriteLine(jsonObj);
Console.WriteLine(jsonObj.ToJson());
Console.WriteLine(jsonObj.ToHashList());
}
[Test]
public void TestDeserialize2()
{
string json = Resources.TestObjectJson2.Trim(); DateTime beginTime = DateTime.Now;
object jsonObj = null;
for (int i = ; i < ; i++)
{
jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
}
DateTime endTime = DateTime.Now;
Console.WriteLine(@"耗时: " + (endTime - beginTime).TotalMilliseconds);
Console.WriteLine(jsonObj);
} [Test]
public void TestSerializeMetaValue()
{
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(DateTime.Now));
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject("AAACCC\"VVV\" CF[] {}, \'\' FCVD"));
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject());
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(false));
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(null)); Console.WriteLine(JsonHelper.JsonSerialize(DateTime.Now));
Console.WriteLine(JsonHelper.JsonSerialize("AAACCC\"VVV\" CF[] {}, \'\' FCVD"));
Console.WriteLine(JsonHelper.JsonSerialize());
Console.WriteLine(JsonHelper.JsonSerialize(false));
Console.WriteLine(JsonHelper.JsonSerialize(null));
}
[Test]
public void TestDeserializeMetaValue()
{
Console.WriteLine(Newtonsoft.Json.JsonConvert.DeserializeObject<DateTime>("\"2017-11-24T22:54:01.7724502+08:00\"")); //反序列化失败
Console.WriteLine(Newtonsoft.Json.JsonConvert.DeserializeObject<string>("\"AAACCC\\\"VVV\\\" CF[] {}, \'\' FCVD\""));
Console.WriteLine(Newtonsoft.Json.JsonConvert.DeserializeObject<int>(""));
Console.WriteLine(Newtonsoft.Json.JsonConvert.DeserializeObject<bool>("false"));
//Console.WriteLine(Newtonsoft.Json.JsonConvert.DeserializeObject<object>(null)); Console.WriteLine(JsonHelper.JsonDeserialize<DateTime>("\"2017-11-24T22:54:01.7724502+08:00\""));
Console.WriteLine(JsonHelper.JsonDeserialize<string>("AAACCC\"VVV\" CF[] {}, \'\' FCVD"));
Console.WriteLine(JsonHelper.JsonDeserialize<int>(""));
Console.WriteLine(JsonHelper.JsonDeserialize<bool>("false"));
Console.WriteLine(JsonHelper.JsonDeserialize<object>(null));
} [Test]
public void TestDeserializeObject()
{
TestClass item = new TestClass();
item.Name = "\\张三'\"'''AAB\r\nBCC\"\"\"";
item.Age = ;
item.Birthday = new DateTime(, , , , , , );
item.Money = 123456789012345678901234567890123456789f;
item.Info = new TestClass {Name = "李四", Age = , Birthday = new DateTime(, , ), Money = }; string webJson = SystemWebJson(item);
Console.WriteLine(webJson);
Console.WriteLine(); string json = Newtonsoft.Json.JsonConvert.SerializeObject(item);
Console.WriteLine(json);
Console.WriteLine(); JsonObject obj = null;
object reObj = null;
DateTime beginTime = DateTime.Now;
for (int i = ; i < ; i++)
{
obj = JsonHelper.JsonDeserializeObject(webJson);
reObj = obj.ToObject(typeof(TestClass));
}
DateTime endTime = DateTime.Now;
Console.WriteLine(@"耗时: " + (endTime - beginTime).TotalMilliseconds);
Console.WriteLine(obj.ToJson());
Console.WriteLine(obj.ToString());
Console.WriteLine(reObj);
}
[Test]
public void TestDeserializeObject2()
{
TestClass item = new TestClass();
item.Name = "\\张三'\"'''AAB\r\nBCC\"\"\"";
item.Age = ;
item.Birthday = new DateTime(, , , , , , );
item.Money = 123456789012345678901234567890123456789f;
item.Info = new TestClass { Name = "李四", Age = , Birthday = new DateTime(, , ), Money = }; string webJson = SystemWebJson(item);
Console.WriteLine(webJson);
Console.WriteLine(); string json = Newtonsoft.Json.JsonConvert.SerializeObject(item);
Console.WriteLine(json);
Console.WriteLine(); object obj = null;
TestClass reObj = null;
DateTime beginTime = DateTime.Now;
for (int i = ; i < ; i++)
{
reObj = Newtonsoft.Json.JsonConvert.DeserializeObject<TestClass>(webJson);
}
DateTime endTime = DateTime.Now;
Console.WriteLine(@"耗时: " + (endTime - beginTime).TotalMilliseconds);
Console.WriteLine(reObj.Birthday.ToString("yyyy-MM-dd HH:mm:ss fffffff"));
Console.WriteLine(reObj);
} [Test]
public void TestSerializeObject()
{
TestClass item = new TestClass();
item.Name = "\\张三'\"'''AAB\r\nBCC\"\"\"";
item.Age = ;
item.Birthday = new DateTime(, , , , , , );
item.Money = 123456789012345678901234567890123456789f;
item.Info = new TestClass { Name = "李四", Age = , Birthday = new DateTime(, , ), Money = }; string json = null;
DateTime beginTime = DateTime.Now;
for (int i = ; i < ; i++)
{
json = JsonHelper.JsonSerialize(item);
}
DateTime endTime = DateTime.Now;
Console.WriteLine(@"耗时: " + (endTime - beginTime).TotalMilliseconds);
Console.WriteLine(json);
}
[Test]
public void TestSerializeObject2()
{
TestClass item = new TestClass();
item.Name = "\\张三'\"'''AAB\r\nBCC\"\"\"";
item.Age = ;
item.Birthday = new DateTime(, , , , , , );
item.Money = 123456789012345678901234567890123456789f;
item.Info = new TestClass { Name = "李四", Age = , Birthday = new DateTime(, , ), Money = }; string json = null;
DateTime beginTime = DateTime.Now;
for (int i = ; i < ; i++)
{
json = Newtonsoft.Json.JsonConvert.SerializeObject(item);
}
DateTime endTime = DateTime.Now;
Console.WriteLine(@"耗时: " + (endTime - beginTime).TotalMilliseconds);
Console.WriteLine(json);
} [Test]
public void TestArray()
{
Console.WriteLine(typeof(string[]));
Console.WriteLine(Array.CreateInstance(typeof(string), ));
Console.WriteLine(typeof(List<>).IsGenericTypeDefinition); //true
Console.WriteLine(typeof(List<string>).IsGenericTypeDefinition); //false
Console.WriteLine(typeof(IList<>).IsAssignableFrom(typeof(List<>)));
Console.WriteLine(typeof(IList<>).IsAssignableFrom(typeof(List<string>))); Console.WriteLine(typeof(IList).IsAssignableFrom(typeof(List<string>)));
Console.WriteLine(typeof(List<>).IsAssignableFrom(typeof(List<string>))); Console.WriteLine(typeof(IList).IsAssignableFrom(typeof(TestListClass))); //true
Console.WriteLine(typeof(IList<>).IsAssignableFrom(typeof(TestListClass))); //false Console.WriteLine(typeof(TestListClass).GetGenericArguments().Length); //
Console.WriteLine(JsonList.GetListElementType(typeof(TestListClass))); //
Console.WriteLine(typeof(string[]).GetElementType()); // }
[Test]
public void TestTimeStamp()
{
DateTime time = Convert.ToDateTime("1993-04-15T10:20:35.987654321");
long stamp = JsonHelper.DateTimeToStamp(time);
DateTime time2 = JsonHelper.StampToDateTime(stamp); Console.WriteLine(time.ToString("yyyy-MM-dd HH:mm:ss fffffff"));
Console.WriteLine(time2.ToString("yyyy-MM-dd HH:mm:ss fffffff"));
}
[Test]
public void TestStringReader()
{
StringReader reader = new StringReader(Resources.TestObjectJson2); int len = ;
while (true)
{
char c = (char)reader.Read();
Console.Write(c);
Console.Write((char)reader.Peek());
len++;
if (len >= )
break;
}
} private string SystemWebJson(object obj)
{
JavaScriptSerializer ser = new JavaScriptSerializer();
string json = ser.Serialize(obj);
return json;
} public class TestClass
{
public string Name { get; set; }
public int Age { get; set; }
public DateTime Birthday { get; set; }
public TestClass Info { get; set; }
public float Money { get; set; } }
public class TestListClass : List<string>
{ } } }
相关思考:
其实,不想用 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 结构:
{ "age":52, "name":"Jim \u0027\u0027\u6211\u7231\u4f60\u000d\u000aABC |||| \u2A6D6 Carrey \"Love\" :[],{} AAA \'CCC\' ", "jsnFO":{ "age":76, "name":"Morgan Freeman \"Love\" :[],{} AAA \'CCC\' ", "jsnSO":{ "age":83, "name":"Clint Eastwood \"Love\" :[],{} AAA \'CCC\' ", "jsnTO":{ "age":81, "name":"Michael Caine \"Love\" :[],{} AAA \'CCC\' ", "messages":[ "You wouldn't hit a man..", "At this point, I'd set you..", "You know, your bobby dangler.." ] }, "messages":[ "This is the AK-47 assault..", "Are you feeling lucky.. \"Love\" :[],{} AAA \'CCC\' Are you feeling lucky.. \"Love\" :[],{} AAA \'CCC\' FCD", "When a naked man's chasing a.." ] }, "messages":[ "I once heard a wise man..", "Well, what is it today? More..", "Bruce... I'm God. Circumstances have.. \"Love\" :[],{} AAA \'CCC\' " ] }, "messages":[ "Hey, maybe I will give you a call.. \"Love\" :[],{} AAA \'CCC\' ", "Excuse me, I'd like to ask you a few..", "Brain freeze. Alrighty Then I just heard.." ] }
PDF属性串:
<</Type/Page/MediaBox [0 0 595 842]
/Rotate 0/Parent 3 0 R
/Resources<</ProcSet[/PDF /Text]
/ExtGState 14 0 R
/Font 15 0 R
>>
/Contents 5 0 R
>>
<</Limits[(wl2)(wl48)]
Names[(wl2) 337 0 R
(wl20) 355 0 R
(wl21) 356 0 R
(wl22) 357 0 R
(wl23) 358 0 R
(wl24) 359 0 R
(wl25) 360 0 R
(wl26) 361 0 R
(wl27) 362 0 R
(wl28) 363 0 R
(wl29) 364 0 R
(wl3) 338 0 R
(wl30) 365 0 R
(wl31) 366 0 R
(wl32) 367 0 R
(wl33) 368 0 R
(wl34) 369 0 R
(wl35) 370 0 R
(wl36) 371 0 R
(wl37) 372 0 R
(wl38) 373 0 R
(wl39) 374 0 R
(wl4) 339 0 R
(wl40) 375 0 R
(wl41) 376 0 R
(wl42) 377 0 R
(wl43) 378 0 R
(wl44) 379 0 R
(wl45) 380 0 R
(wl46) 381 0 R
(wl47) 382 0 R
(wl48) 383 0 R
]
>>
栈结构字符串解析算法 的 调用方式:
//创建一个 栈结构字符串 解析方案
StrStack stack = new StrStack();
stack.RemoveEmptyAndLineEnd = true;
stack.SetHasChildRule('{', '}', null);
stack.SetHasChildRule('[', ']', null);
stack.SetNoChildRule('"', '"', (l, i, c, s) => { return i <= || l[i - ] != '\\'; });
stack.SetNoChildRule('\'', '\'', (l, i, c, s) => { return i <= || l[i - ] != '\\'; });
stack.SetConstRule("null", null);
stack.SetConstRule("true", null);
stack.SetConstRule("false", null);
stack.SetNumericRule();
stack.SetCharRule(';', null);
stack.SetCharRule(',', null);
stack.SetCharRule(':', null); //通过方案, 解析出所有 栈结构对象(包括嵌套逻辑)
List<StrStackObject> listItem = stack.Analyze(str);
StrStackObject item = listItem[]; //栈对象 和 嵌套逻辑有了, 接下来就是转换成 自己的 Json算法对象、 PDF算法对象了...