在處理JSON類型的數據時,定義了很多JSON類型。經常需要用到序列化和反序列化。剛開始接觸到這個問題時,我給每個JSON類型都增加了類似下方的代碼。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; namespace 企業微信賬號 { [DataContract] public class JToken { [DataMember] public string userid { get; set; } [DataMember] public string name { get; set; } [DataMember] public List<long> department { get; set; } public override string ToString() { var serializer = new DataContractJsonSerializer(this.GetType()); using (var ms = new MemoryStream()) { serializer.WriteObject(ms, this); var b = ms.ToArray(); var s = Encoding.UTF8.GetString(b); return s; } } public static JToken FromString(string s) { var serializer = new DataContractJsonSerializer(typeof(JToken)); var b = Encoding.UTF8.GetBytes(s); using (var ms = new MemoryStream(b)) { var o = (JToken)serializer.ReadObject(ms); return o; } } } }
使用上面的代碼JSON類型對象的序列化和反序列化問題。隨着項目的進展,定義了越來越多的JSON類型,每次定義完字段后都要把這兩個方法復制進去,再稍作調整。隨着JSON類型數量的增加,感覺再使用這種方式,效率太低了,考慮改用其他方式。后來增加了JSON類型的操作類JsonConverter。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; namespace 企業微信賬號 { public class Program { public static void Test() { var strToken = "{\"userid\":\"admin\",\"name\":\"系統管理員\",\"department\":[1]}"; var token = JsonConverter.FromString<JToken>(strToken); } } [DataContract] public class JToken { [DataMember] public string userid { get; set; } [DataMember] public string name { get; set; } [DataMember] public List<long> department { get; set; } } public static class JsonConverter { public static string ToString(object o) { var serializer = new DataContractJsonSerializer(o.GetType()); using (var ms = new MemoryStream()) { serializer.WriteObject(ms, o); var b = ms.ToArray(); var s = Encoding.UTF8.GetString(b); return s; } } public static T FromString<T>(string s) { var serializer = new DataContractJsonSerializer(typeof(T)); var b = Encoding.UTF8.GetBytes(s); using (var ms = new MemoryStream(b)) { var o = (T)serializer.ReadObject(ms); return o; } } } }
用得時間長了,還是覺得代碼不美觀。例如:var token = JsonConverter.FromString<JToken>(strToken),在調用的時候還需要在調用函數上指定結果類型<JToken>。於是開始在網上找資料,看看能不能再繼續進行優化。最初的目的是想在父類中寫靜態方法,用子類去繼承靜態方法。后來發現在子類雖然能繼承到方法,但是根本拿不到子類的類型。
后來查到可以將父類定義成一個泛型的類,這樣在定義子類時,可以在寫繼承時通過下面的形式將子類的類型傳進父類的靜態方法中
class A<T> { public static T func(string s) { } } class A1 : A<A1> { }
最后,將所有的JSON類型都增加了一個繼承的父類JObject。在JObject類中實現序列化和反序列化,然后每個JSON類都繼承JObject類,這樣每個類只要繼承JObject類就可以了。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; namespace 企業微信賬號 { public class Program { public static void Test() { var token = new JToken() { name = "系統管理員", userid = "admin", department = new List<long>() { 1 } }; var s = token.ToString(); var obj = JToken.FromString(s); } } [DataContract] public class JToken : JObject<JToken> { [DataMember] public string userid { get; set; } [DataMember] public string name { get; set; } [DataMember] public List<long> department { get; set; } } [DataContract] public class JObject<T> { public override string ToString() { var serializer = new DataContractJsonSerializer(this.GetType()); using (var ms = new MemoryStream()) { serializer.WriteObject(ms, this); var b = ms.ToArray(); var s = Encoding.UTF8.GetString(b); return s; } } public static T FromString(string s) { var serializer = new DataContractJsonSerializer(typeof(T)); var b = Encoding.UTF8.GetBytes(s); using (var ms = new MemoryStream(b)) { var o = (T)serializer.ReadObject(ms); return o; } } } }