From 208fdf233b96b061a4c681ef90fc36f72f4f8977 Mon Sep 17 00:00:00 2001 From: Igor Levochkin Date: Sun, 19 Nov 2017 20:15:54 +0200 Subject: [PATCH] More flexible RegisterCustomType --- fastJSON/JSON.cs | 17 ++++++++------- fastJSON/JsonSerializer.cs | 8 +++++--- fastJSON/Reflection.cs | 42 +++++++++++++++++++++----------------- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/fastJSON/JSON.cs b/fastJSON/JSON.cs index 06aa486..eb36328 100644 --- a/fastJSON/JSON.cs +++ b/fastJSON/JSON.cs @@ -10,8 +10,7 @@ namespace fastJSON { - public delegate string Serialize(object data); - public delegate object Deserialize(string data); + public delegate T2 ConvertDelegate(T1 t1); public sealed class JSONParameters { @@ -308,9 +307,9 @@ public static string Beautify(string input, byte spaces) /// /// /// - public static void RegisterCustomType(Type type, Serialize serializer, Deserialize deserializer) + public static void RegisterCustomType(ConvertDelegate serializer, ConvertDelegate deserializer) { - Reflection.Instance.RegisterCustomType(type, serializer, deserializer); + Reflection.Instance.RegisterCustomType(typeof(T1), typeof(T2), a => serializer((T1)a), a => deserializer((T2)a)); } /// /// Clear the internal reflection cache so you can start from new (you will loose performance) @@ -450,6 +449,7 @@ private object RootHashTable(List o) private object ChangeType(object value, Type conversionType) { + CustomConverter cc; if (conversionType == typeof(int)) { string s = value as string; @@ -478,8 +478,9 @@ private object ChangeType(object value, Type conversionType) else if (conversionType == typeof(DateTimeOffset)) return CreateDateTimeOffset((string)value); - else if (Reflection.Instance.IsTypeRegistered(conversionType)) - return Reflection.Instance.CreateCustom((string)value, conversionType); + else if (Reflection.Instance.customTypes.TryGetValue(conversionType, out cc)) + return cc.deserialize(value); + // 8-30-2014 - James Brooks - Added code for nullable types. if (IsNullable(conversionType)) @@ -773,7 +774,6 @@ internal object ParseDictionary(Dictionary d, Dictionary)v, pi.pt, pi.GenericTypes, globaltypes); break; case myPropInfoType.NameValue: oset = CreateNV((Dictionary)v); break; case myPropInfoType.StringDictionary: oset = CreateSD((Dictionary)v); break; - case myPropInfoType.Custom: oset = Reflection.Instance.CreateCustom((string)v, pi.pt); break; default: { if (pi.IsGenericType && pi.IsValueType == false && v is List) @@ -793,6 +793,9 @@ internal object ParseDictionary(Dictionary d, Dictionary serialize; + public ConvertDelegate deserialize; + } internal sealed class Reflection { @@ -100,22 +108,15 @@ private Reflection() #region json custom types // JSON custom - internal SafeDictionary _customSerializer = new SafeDictionary(); - internal SafeDictionary _customDeserializer = new SafeDictionary(); - - internal object CreateCustom(string v, Type type) - { - Deserialize d; - _customDeserializer.TryGetValue(type, out d); - return d(v); - } + //internal SafeDictionary _customSerializer = new SafeDictionary(); + //internal SafeDictionary _customDeserializer = new SafeDictionary(); + internal Dictionary customTypes = new Dictionary(); - internal void RegisterCustomType(Type type, Serialize serializer, Deserialize deserializer) + internal void RegisterCustomType(Type type, Type t, ConvertDelegate serializer, ConvertDelegate deserializer) { if (type != null && serializer != null && deserializer != null) { - _customSerializer.Add(type, serializer); - _customDeserializer.Add(type, deserializer); + customTypes.Add(type, new CustomConverter() { deserialize = deserializer, serialize = serializer, t = t }); // reset property cache Instance.ResetPropertyCache(); } @@ -123,10 +124,10 @@ internal void RegisterCustomType(Type type, Serialize serializer, Deserialize de internal bool IsTypeRegistered(Type t) { - if (_customSerializer.Count == 0) + if (customTypes.Count == 0) return false; - Serialize s; - return _customSerializer.TryGetValue(t, out s); + CustomConverter s; + return customTypes.TryGetValue(t, out s); } #endregion @@ -234,6 +235,11 @@ private myPropInfo CreateMyProp(Type t, string name) myPropInfo d = new myPropInfo(); myPropInfoType d_type = myPropInfoType.Unknown; + d.pt = t; + CustomConverter cc; + if (customTypes.TryGetValue(t, out cc)) + t = cc.t; + if (t == typeof(int) || t == typeof(int?)) d_type = myPropInfoType.Int; else if (t == typeof(long) || t == typeof(long?)) d_type = myPropInfoType.Long; else if (t == typeof(string)) d_type = myPropInfoType.String; @@ -264,8 +270,7 @@ private myPropInfo CreateMyProp(Type t, string name) else if (t == typeof(DataSet)) d_type = myPropInfoType.DataSet; else if (t == typeof(DataTable)) d_type = myPropInfoType.DataTable; #endif - else if (IsTypeRegistered(t)) - d_type = myPropInfoType.Custom; + if (t.IsValueType && !t.IsPrimitive && !t.IsEnum && t != typeof(decimal)) d.IsStruct = true; @@ -279,7 +284,6 @@ private myPropInfo CreateMyProp(Type t, string name) d.bt = t.GetGenericArguments()[0]; } - d.pt = t; d.Name = name; d.changeType = GetChangeType(t); d.Type = d_type;