使用基礎類
using System; using System.Collections.Generic; namespace JSON { /// <summary> /// 拓展Linq /// </summary> public static class TLinq { /// <summary> /// 跳過指定的數量的序列中的元素,然后回傳剩余元素 /// </summary> /// <typeparam name="T">資料型別</typeparam> /// <param name="arr">原陣列</param> /// <param name="skipCount">跳過的長度</param> /// <returns></returns> public static T[] Skip<T>(this T[] arr, int skipCount) { if (arr.Length > skipCount) { T[] res = new T[arr.Length - skipCount]; int num = 0; for (int i = skipCount; i < arr.Length; i++) { res[num] = arr[i]; num++; } return res; } else { throw new ArgumentException("skipCount大于arr長度"); } } /// <summary> /// 回傳此陣列的指定長度 /// </summary> /// <typeparam name="T">資料型別</typeparam> /// <param name="arr">原陣列</param> /// <param name="length">指定長度</param> /// <returns></returns> public static T[] Take<T>(this T[] arr, int length) { if (length < arr.Length) { T[] res = new T[length]; for (int i = 0; i < length; i++) { res[i] = arr[i]; } return res; } else { throw new ArgumentException("length大于arr長度"); } } /// <summary> /// 反轉元素 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="arr"></param> /// <returns></returns> public static T[] Reverse<T>(this T[] arr) { List<T> list = new List<T>(); for (int i = arr.Length - 1; i >= 0; i--) { list.Add(arr[i]); } return list.ToArray(); } /// <summary> /// 分割一次,從尾開始,回傳剩余 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="arr"></param> /// <param name="last"></param> /// <param name="split"></param> /// <returns>回傳剩余</returns> public static T[] SplitLast<T>(this T[] arr, out T[] last, params T[] split) { List<T> list = new List<T>(); int count = 0; if (null != split && split.Length > 0) { for (int i = arr.Length - 1; i >= 0; i--) { if (arr[i].Equals(split[split.Length - 1 - count])) { count++; if (count == split.Length) { last = Reverse(list.ToArray()); return arr.Take(arr.Length - (arr.Length - i)); } } else { if (i < arr.Length - 1 && count > 0) { list.Add(arr[i + 1]); } list.Add(arr[i]); count = 0; } } } last = default; return default; } /// <summary> /// 分割一次,從首開始,回傳剩余 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="arr"></param> /// <param name="first"></param> /// <param name="split"></param> /// <returns>回傳剩余</returns> public static T[] SplitFirst<T>(this T[] arr, out T[] first, params T[] split) { first = default; List<T> list = new List<T>(); int count = 0; if (null != split && split.Length > 0) { for (int i = 0; i < arr.Length; i++) { if (arr[i].Equals(split[count])) { count++; if (count == split.Length) { first = list.ToArray(); return i < arr.Length - 1 ? arr.Skip(i + 1) : default; } } else { if (i > 0 && count > 0) { list.Add(arr[i - 1]); } list.Add(arr[i]); count = 0; } } } return default; } /// <summary> /// 查看陣列是否包含此欄位 /// </summary> /// <typeparam name="T">陣列型別</typeparam> /// <param name="arr">陣列實體</param> /// <param name="any">比較方法</param> /// <returns></returns> public static bool Any<T>(this T[] arr, TLinq<T, bool> any) { foreach (var obj in arr) if (any(obj)) return true; return false; } /// <summary> /// 獲取相同數 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="arr"></param> /// <param name="same"></param> /// <returns></returns> public static int Same<T>(this T[] arr, TLinq<T, bool> same) { int resNum = 0; foreach (var obj in arr) if (same(obj)) resNum++; return resNum; } /// <summary> /// 頭相同個數 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="arr"></param> /// <param name="same"></param> /// <returns></returns> public static int SameHead<T>(this T[] arr, TLinq<T, bool> same) { int resNum = 0; foreach (var obj in arr) { if (same(obj)) { resNum++; continue; } else { break; } } return resNum; } /// <summary> /// 尾相同個數 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="arr"></param> /// <param name="same"></param> /// <returns></returns> public static int SameTail<T>(this T[] arr, TLinq<T, bool> same) { int resNum = 0; for (int i = arr.Length - 1; i >= 0; i--) { if (same(arr[i])) { resNum++; continue; } else { break; } } return resNum; } } /// <summary> /// 拓展Linq /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="T1"></typeparam> /// <param name="obj">引數物件</param> /// <returns></returns> public delegate T1 TLinq<in T, out T1>(T obj); }
物件轉Json
using System; using System.Collections; using System.Reflection; using System.Text; namespace JSON { /// <summary> /// 模型轉為JSON /// </summary> public static class ToJsonEx { /// <summary> /// 物件轉換為Json /// </summary> /// <param name="obj"></param> /// <param name="ignores">忽略輸出的屬性(不區分大小寫)</param> /// <returns></returns> public static string ToJson(this Object obj, params string[] ignores) { return ToJson(obj, false, ignores); } /// <summary> /// 轉換為全部屬性值是字串的Json /// </summary> /// <param name="obj"></param> /// <param name="ignores">忽略輸出的屬性(不區分大小寫)</param> /// <returns></returns> public static string ToAllStringJson(this Object obj, params string[] ignores) { return ToJson(obj, true, ignores); } /// <summary> /// 物件轉換為Json /// </summary> /// <param name="obj">物件實體</param> /// <param name="isStr">是否全部輸出為字串</param> /// <param name="ignores">忽略輸出的屬性(不區分大小寫)</param> /// <returns>Json字串</returns> public static string ToJson(this Object obj, bool isStr = false, params string[] ignores) { switch (obj) { //TODO:特殊型別轉換添加到此處 case Guid value: return $"\"{value.ToString()}\""; case IList value: return IListToJson(value, isStr, ignores); case IDictionary value: return IDictionaryToJson(value, isStr, ignores); case Object value: return ObjectToJson(obj, isStr, ignores); default: throw new NotImplementedException("無法識別物件!"); } } #region 基礎轉換 /// <summary> /// 轉換值為Json字串 /// </summary> /// <param name="value">值</param> /// <param name="isStr">是否轉為字串</param> /// <param name="ignores">忽略欄位</param> /// <returns></returns> private static string ValueToJson(this object value, bool isStr = false, params string[] ignores) { if (null == value) return "null"; string str_property = string.Empty; var type = value.GetType(); switch (type.BaseType.Name) { case "ValueType": case "Object": //獲取此屬性型別標識 TypeCode code = Convert.GetTypeCode(value); switch (code) { case TypeCode.Empty: str_property += "null"; break; case TypeCode.Object: str_property += ToJson(value, isStr, ignores); break; case TypeCode.Boolean: str_property += isStr ? $"\"{value.ToString().ToLower()}\"" : value.ToString().ToLower(); break; case TypeCode.Int32: case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: str_property += isStr ? $"\"{value}\"" : value; break; case TypeCode.Char: str_property += $"\"{(((Char)value != Char.MinValue) ? value : string.Empty)}\""; break; case TypeCode.String: str_property += $"\"{(((String)value != String.Empty) ? value : string.Empty)}\""; break; case TypeCode.DateTime: str_property += $"\"{Convert.ToDateTime(value).ToString("yyyy-MM-dd HH:mm:ss")}\""; break; case TypeCode.DBNull: default: throw new NotImplementedException("無法識別物件!"); } break; case "Enum": str_property += isStr ? $"\"{value.GetHashCode()}\"" : value.GetHashCode().ToString(); break; default: str_property += ToJson(value, isStr, ignores); break; } return str_property; } /// <summary> /// 物件轉換為Json /// </summary> /// <param name="obj">物件實體</param> /// <param name="isStr"></param> /// <param name="ignores">忽略輸出的屬性</param> /// <returns>Json字串</returns> private static string ObjectToJson(this Object obj, bool isStr = false, params string[] ignores) { PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); //Object 頭 StringBuilder builder = new StringBuilder("{"); foreach (var property in properties) { if (null != ignores && ignores.Length > 0 && ignores.Any(g => g.ToLower() == property.Name.ToLower())) { continue; } else { //此屬性json表示字符 string str_property = string.Empty; //屬性名稱格式 str_property = $"\"{property.Name}\":"; //獲取此屬性值 Object value =https://www.cnblogs.com/Jzs001/p/ property.GetValue(obj); //添加此屬性值 str_property += ValueToJson(value, isStr, ignores); //是否添加間隔符 builder.Append(str_property + ','); } } //有內容時去除多余間隔符 if (properties.Length > 0 && builder.Length > 1) { //去除多余間隔符 builder.Remove(builder.Length - 1, 1); } //Object 尾 builder.Append("}"); return builder.ToString(); } /// <summary> /// 組型別轉換為Json /// </summary> /// <param name="list">組型別</param> /// <param name="isStr"></param> /// <param name="ignores">忽略輸出的屬性</param> /// <returns>Json字串</returns> private static string IListToJson(this IList list, bool isStr = false, params string[] ignores) { StringBuilder builder = new StringBuilder("["); //轉換值為json字串 foreach (var value in list) builder.Append(ValueToJson(value, isStr, ignores) + ','); //有內容時去除多余間隔符 if (list.Count > 0) { //去除多余間隔符 builder.Remove(builder.Length - 1, 1); } //添加結尾符 builder.Append("]"); return builder.ToString(); } /// <summary> /// 字典型別轉換為Json字串 /// </summary> /// <param name="dictionary"></param> /// <param name="isStr"></param> /// <param name="ignores"></param> /// <returns>Json字串</returns> private static string IDictionaryToJson(this IDictionary dictionary, bool isStr = false, params string[] ignores) { StringBuilder builder = new StringBuilder("["); foreach (var key in dictionary.Keys) { var value =https://www.cnblogs.com/Jzs001/p/ dictionary[key]; //外邊界 builder.Append("["); //轉換key builder.Append(ValueToJson(key, isStr, ignores)); //分隔 builder.Append(","); //轉換value builder.Append(ValueToJson(value, isStr, ignores)); //尾邊界 builder.Append("],"); } //有內容時去除多余間隔符 if (dictionary.Count > 0) { //去除多余間隔符 builder.Remove(builder.Length - 1, 1); } builder.Append("]"); return builder.ToString(); } #endregion } }
Json轉物件
using System; using System.Collections; using System.Collections.Generic; using System.Reflection; namespace JSON { /* Json轉obj * 得到轉換型別 * 決議Json,決議為此物件一個屬性跟一個此屬性的字串,為object時,回圈決議(object) * * */ /// <summary> /// Json轉化為Object /// </summary> public static class ToObjectEX { /* * Object Json: {key:value} [value,value] [[key,value],[key,value]] value */ /// <summary> /// 轉換Json為指定型別 /// </summary> /// <typeparam name="T">物件型別</typeparam> /// <param name="objectJson">Object的Json字串</param> /// <returns>指定型別實體</returns> public static T ToObject<T>(string objectJson) { return (T)ToObject(typeof(T), objectJson); } /* * Object Json: {key:value} [value,value] [[key,value],[key,value]] value */ /// <summary> /// 轉換Json為指定型別 /// </summary> /// <param name="type">物件型別</param> /// <param name="objectJson">Object的Json字串</param> /// <returns>指定型別實體</returns> public static object ToObject(Type type, string objectJson) { switch (type.Name) { case "Object": //TODO:無法決議型別為Object的實體[默認轉為字串] return objectJson; case "Guid": return new Guid(objectJson.Trim('"')); case "List`1": return JsonToIList(type, objectJson); case "Dictionary`2": return JsonToIDictionary(type, objectJson); default: if (type.BaseType.Name == "Array") { return JsonToArray(type, objectJson); } else { return JsonToObject(type, objectJson); } } } #region 基礎轉換 /* * Value Json: value */ /// <summary> /// 轉換Json為指定型別值 /// </summary> /// <param name="type">物件型別</param> /// <param name="valueJson">值的Json字串</param> /// <returns>指定型別實體</returns> private static object JsonToValue(Type type, string valueJson) { if ("null" != valueJson) { valueJson = RemoveSE(valueJson); //此屬性的型別 TypeCode typeCode = Type.GetTypeCode(type); switch (typeCode) { case TypeCode.Object: return ToObject(type, valueJson); case TypeCode.Char: if (string.IsNullOrEmpty(valueJson)) { return Char.MinValue; } goto case TypeCode.Single; case TypeCode.String: if (string.IsNullOrEmpty(valueJson)) { return string.Empty; } goto case TypeCode.Single; case TypeCode.DateTime: case TypeCode.Boolean: case TypeCode.Int32: case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Double: case TypeCode.Decimal: case TypeCode.Single: if (!string.IsNullOrEmpty(valueJson)) { return Convert.ChangeType(valueJson, typeCode); } break; case TypeCode.Empty: case TypeCode.DBNull: default: throw new NotImplementedException("未知型別"); } } return default; } /* * Object Json: {key:value} */ /// <summary> /// 轉換Json為指定型別 /// </summary> /// <param name="type">物件型別</param> /// <param name="objectJson">Json字串</param> /// <returns>指定型別實體</returns> private static object JsonToObject(Type type, string objectJson) { //創建此型別實體 var obj = Activator.CreateInstance(type); //獲取物件型別 PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); //決議ObjectJson Dictionary<string, string> pairs = ParsingObjectJson(objectJson); //屬性不為空 和 決議字串不為空 if (properties.Length > 0 && pairs.Count > 0) { //此物件的所有屬性 foreach (var property in properties) { //Json是否有此屬性 if (pairs.ContainsKey(property.Name)) { //沒有此屬性 或 Value為空 跳過 if (!pairs.ContainsKey(property.Name) || string.IsNullOrEmpty(pairs[property.Name])) continue; //轉換value為型別屬性值 property.SetValue(obj, JsonToValue(property.PropertyType, pairs[property.Name])); } } } else { obj = default; } return obj; } /* * List Json: [value,value] */ /// <summary> /// 轉換Json為指定型別組 /// </summary> /// <param name="type">物件型別</param> /// <param name="ilistJson">List的Json字串</param> /// <returns>指定型別組實體</returns> private static object JsonToIList(Type type, string ilistJson) { if (!string.IsNullOrEmpty(ilistJson) && ilistJson != "[]" && ilistJson != "null") { //初始化此IList var ilist = (IList)Activator.CreateInstance(type); //獲取此實體的物件 var tempType = type.GenericTypeArguments[0]; //決議 List<string> list = ParsingIListJson(ilistJson); if (list.Count > 0) { foreach (var value in list) { ilist.Add(JsonToValue(tempType, value)); } return ilist; } } return default; } /* * Array Json: [value,value] */ /// <summary> /// 轉換Json為指定型別組 /// </summary> /// <param name="type">物件型別</param> /// <param name="arrayJson">Array的Json字串</param> /// <returns>指定型別組實體</returns> private static object JsonToArray(Type type, string arrayJson) { if (!string.IsNullOrEmpty(arrayJson) && arrayJson != "[]" && arrayJson != "null") { //獲取程式集資訊(除型別外) string aqn = new string(type.AssemblyQualifiedName.ToCharArray().SplitFirst(out char[] first, type.FullName.ToCharArray())); //獲取陣列維度 int num = type.Name.ToCharArray().Same(c => c == ']'); //獲取陣列型別 type.Name.ToCharArray().SplitFirst(out char[] arrType, '[', ']'); //陣列型別名稱 String typeName = new String(arrType); //恢復維度 for (int i = 0; i < num - 1; i++) { typeName += "[]"; } //初始化陣列型別 Type objType = Type.GetType(type.Namespace + '.' + typeName + aqn); //決議陣列 List<string> list = ParsingIListJson(arrayJson); //創建陣列,按回傳值長度創建 var iArr = Array.CreateInstance(objType, list.Count); //轉換為陣列值 for (int i = 0; i < list.Count; i++) { iArr.SetValue(JsonToValue(objType, list[i]), i); } return iArr; } return default; } /* * 鍵值對 Json: [[key,value],[key,value]] */ /// <summary> /// 轉換Json為指定型別鍵值對 /// </summary> /// <param name="type">物件型別</param> /// <param name="idictionaryJson">鍵值對的Json字串</param> /// <returns>指定型別鍵值對實體</returns> private static object JsonToIDictionary(Type type, string idictionaryJson) { if (!string.IsNullOrEmpty(idictionaryJson) && idictionaryJson != "[]" && idictionaryJson != "null") { //Key 型別 Type keyType = type.GenericTypeArguments[0]; //Value 型別 Type valueType = type.GenericTypeArguments[1]; //初始化一個此型別實體 var dic = (IDictionary)Activator.CreateInstance(type); //決議鍵值對json Dictionary<string, string> pairs = ParsingIDictionaryJson(idictionaryJson); //鍵值對賦值 foreach (var keyValue in pairs) { dic.Add(JsonToValue(keyType, keyValue.Key), JsonToValue(valueType, keyValue.Value)); } return dic; } return default; } #endregion #region Core /// <summary> /// 決議ObjectJson為鍵值對(Ok-2020年7月3日18點37分)[Core] /// </summary> /// <param name="objectJson">實體Json</param> /// <returns>實體的屬性與值鍵值對</returns> private static Dictionary<string, string> ParsingObjectJson(string objectJson) { Dictionary<string, string> pairs = new Dictionary<string, string>(); if (objectJson != "{}" && objectJson != "null") { string[] jsonArr = objectJson.Split(new string[] { "\":" }, StringSplitOptions.RemoveEmptyEntries); if (null != jsonArr && jsonArr.Length > 0) { int signLen = -1; //標志長度 string key = string.Empty, //key value = https://www.cnblogs.com/Jzs001/p/string.Empty; //value foreach (var str in jsonArr) { signLen += GetSameHead(str); signLen -= GetSameTail(str); //獲取key value char[] resTempValue = https://www.cnblogs.com/Jzs001/p/str.ToCharArray().SplitLast(out char[] resTempKey, ',', '\"'); if (null != resTempValue && null != resTempKey) { if (signLen == 0) { pairs[key] += new string(resTempValue); key = new string(resTempKey); pairs.Add(key, string.Empty); } else { pairs[key] += str + "\":"; } } else { if (pairs.Count > 0) { pairs[key] += str + "\":"; } else { str.ToCharArray().SplitLast(out char[] last, '{', '\"'); key = new String(last); pairs.Add(key, string.Empty); } } } if (pairs.Count >= 1) { //清除最后一次添加的 \": pairs[key] = pairs[key].Remove(pairs[key].Length - 3); } } } return pairs; } /* * IList Json: [value,value] [[value,value],[value,value]] [[[value,value],[value,value]],[[value,value]]] */ /// <summary> /// 決議IListJson為組,支持多維陣列(分割成單個實體Json,Ok 2020年7月4日15點01分)[Core] /// </summary> /// <param name="ilistJson">組Json</param> /// <returns>決議后的值組</returns> private static List<string> ParsingIListJson(string ilistJson) { List<string> list = new List<string>(); int signLen = 0; //標志長度 //去除頭尾 string temp = ilistJson.Remove(0, 1); temp = temp.Remove(temp.Length - 1, 1); string[] arr = temp.Split(','); string value = https://www.cnblogs.com/Jzs001/p/string.Empty; foreach (var str in arr) { signLen += GetSameHead(str); signLen -= GetSameTail(str); value += str; if (signLen == 0) { list.Add(value); value = string.Empty; } else { value += ','; } } return list; } /* * 鍵值對 Json: [[key,value],[key,value]] */ /// <summary> /// 決議IDictionaryJson為鍵值對 /// </summary> /// <param name="idictionaryJson">鍵值對Json</param> /// <returns>決議后的鍵值對</returns> private static Dictionary<string, string> ParsingIDictionaryJson(string idictionaryJson) { Dictionary<string, string> pairs = new Dictionary<string, string>(); var arr = ParsingIListJson(idictionaryJson); foreach (var item in arr) { var tempArr = ParsingIListJson(item); if (tempArr.Count == 2) { pairs.Add(tempArr[0], tempArr[1]); } else { pairs.Add(tempArr[0], string.Empty); } } return pairs; } /// <summary> /// 獲取相同頭數量 /// </summary> /// <param name="jsonValue"></param> /// <returns></returns> private static int GetSameHead(string jsonValue) { int resNum = 0; resNum += jsonValue.ToCharArray().Same(c => c == '{'); resNum += jsonValue.ToCharArray().Same(c => c == '['); return resNum; } /// <summary> /// 獲取相同結尾數量 /// </summary> /// <param name="jsonValue"></param> /// <returns></returns> private static int GetSameTail(string jsonValue) { int resNum = 0; resNum += jsonValue.ToCharArray().Same(c => c == '}'); resNum += jsonValue.ToCharArray().Same(c => c == ']'); return resNum; } /// <summary> /// 洗掉首尾 \" 符 /// </summary> /// <param name="str"></param> /// <returns></returns> private static string RemoveSE(string str) { if (str.StartsWith("\"")) { str = str.Remove(0, 1); } if (str.EndsWith("\"")) { str = str.Remove(str.Length - 1, 1); } return str; } #endregion } }
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/9610.html
標籤:C#
上一篇:C# 實作TXT檔案轉Table
下一篇:C# 9.0 終于來了, Top-level programs 和 Partial Methods 兩大新特性探究
