Esempio n. 1
0
        public static IDictionary ParseIDictionary(StringSegment value, Type dictType)
        {
            if (!value.HasValue)
            {
                return(null);
            }

            var index = VerifyAndGetStartIndex(value, dictType);

            var valueParseMethod = Serializer.GetParseStringSegmentFn(typeof(object));

            if (valueParseMethod == null)
            {
                return(null);
            }

            //var to = (IDictionary)dictType.CreateInstance();
            var to = ActivatorUtils.FastCreateInstance <IDictionary>(dictType);

            if (JsonTypeSerializer.IsEmptyMap(value, index))
            {
                return(to);
            }

            var valueLength = value.Length;

            while (index < valueLength)
            {
                var keyValue = Serializer.EatMapKey(value, ref index);
                Serializer.EatMapKeySeperator(value, ref index);
                var elementStartIndex = index;
                var elementValue      = Serializer.EatTypeValue(value, ref index);
                if (!keyValue.HasValue)
                {
                    continue;
                }

                var mapKey = valueParseMethod(keyValue);

                if (elementStartIndex < valueLength)
                {
                    Serializer.EatWhitespace(value, ref elementStartIndex);
                    to[mapKey] = DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value, value.GetChar(elementStartIndex));
                }
                else
                {
                    to[mapKey] = valueParseMethod(elementValue);
                }

                Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
            }

            return(to);
        }
Esempio n. 2
0
        public static void InitAot <T>()
        {
            var hold = DeserializeBuiltin <T> .Parse;

            hold = DeserializeArray <T[], TSerializer> .Parse;
            DeserializeType <TSerializer> .ExtractType(default(ReadOnlySpan <char>));

            DeserializeArrayWithElements <T, TSerializer> .ParseGenericArray(default(ReadOnlySpan <char>), null);

            DeserializeCollection <TSerializer> .ParseCollection <T>(default(ReadOnlySpan <char>), null, null);

            DeserializeListWithElements <T, TSerializer> .ParseGenericList(default(ReadOnlySpan <char>), null, null);
        }
Esempio n. 3
0
        public static void InitAot <T>()
        {
            var hold = DeserializeBuiltin <T> .Parse;

            hold = DeserializeArray <T[], TSerializer> .Parse;
            DeserializeType <TSerializer> .ExtractType(null);

            DeserializeArrayWithElements <T, TSerializer> .ParseGenericArray(null, null);

            DeserializeCollection <TSerializer> .ParseCollection <T>(null, null, null);

            DeserializeListWithElements <T, TSerializer> .ParseGenericList(null, null, null);
        }
        public static IDynamicMetaObjectProvider ParseDynamic(string value)
        {
            var index = VerifyAndGetStartIndex(value, typeof(ExpandoObject));

            var result = new ExpandoObject();

            if (JsonTypeSerializer.IsEmptyMap(value))
            {
                return(result);
            }

            var container = (IDictionary <String, Object>)result;

            var tryToParsePrimitiveTypes = JsConfig.TryToParsePrimitiveTypeValues;

            var valueLength = value.Length;

            while (index < valueLength)
            {
                var keyValue = Serializer.EatMapKey(value, ref index);
                Serializer.EatMapKeySeperator(value, ref index);
                var elementValue = Serializer.EatValue(value, ref index);

                var mapKey = Serializer.UnescapeString(keyValue);

                if (JsonUtils.IsJsObject(elementValue))
                {
                    container[mapKey] = ParseDynamic(elementValue);
                }
                else if (JsonUtils.IsJsArray(elementValue))
                {
                    container[mapKey] = DeserializeList <List <object>, TSerializer> .Parse(elementValue);
                }
                else if (tryToParsePrimitiveTypes)
                {
                    container[mapKey] = DeserializeType <TSerializer> .ParsePrimitive(elementValue) ?? Serializer.UnescapeString(elementValue);
                }
                else
                {
                    container[mapKey] = Serializer.UnescapeString(elementValue);
                }

                Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
            }

            return(result);
        }
        public static IDictionary <TKey, TValue> ParseDictionary <TKey, TValue>(
            StringSegment value, Type createMapType,
            ParseStringSegmentDelegate parseKeyFn, ParseStringSegmentDelegate parseValueFn)
        {
            if (!value.HasValue)
            {
                return(null);
            }

            var tryToParseItemsAsDictionaries =
                JsConfig.ConvertObjectTypesIntoStringDictionary && typeof(TValue) == typeof(object);
            var tryToParseItemsAsPrimitiveTypes =
                JsConfig.TryToParsePrimitiveTypeValues && typeof(TValue) == typeof(object);

            var index = VerifyAndGetStartIndex(value, createMapType);

            var to = createMapType == null
                ? new Dictionary <TKey, TValue>()
                : (IDictionary <TKey, TValue>)createMapType.CreateInstance();

            if (JsonTypeSerializer.IsEmptyMap(value, index))
            {
                return(to);
            }

            var valueLength = value.Length;

            while (index < valueLength)
            {
                var keyValue = Serializer.EatMapKey(value, ref index);
                Serializer.EatMapKeySeperator(value, ref index);
                var elementStartIndex = index;
                var elementValue      = Serializer.EatTypeValue(value, ref index);
                if (!keyValue.HasValue)
                {
                    continue;
                }

                var mapKey = (TKey)parseKeyFn(keyValue);

                if (tryToParseItemsAsDictionaries)
                {
                    Serializer.EatWhitespace(value, ref elementStartIndex);
                    if (elementStartIndex < valueLength && value.GetChar(elementStartIndex) == JsWriter.MapStartChar)
                    {
                        var tmpMap = ParseDictionary <TKey, TValue>(elementValue, createMapType, parseKeyFn, parseValueFn);
                        if (tmpMap != null && tmpMap.Count > 0)
                        {
                            to[mapKey] = (TValue)tmpMap;
                        }
                    }
                    else if (elementStartIndex < valueLength && value.GetChar(elementStartIndex) == JsWriter.ListStartChar)
                    {
                        to[mapKey] = (TValue)DeserializeList <List <object>, TSerializer> .ParseStringSegment(elementValue);
                    }
                    else
                    {
                        to[mapKey] = (TValue)(tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength
                                        ? DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value, value.GetChar(elementStartIndex))
                                        : parseValueFn(elementValue));
                    }
                }
                else
                {
                    if (tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength)
                    {
                        Serializer.EatWhitespace(value, ref elementStartIndex);
                        to[mapKey] = (TValue)DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value, value.GetChar(elementStartIndex));
                    }
                    else
                    {
                        to[mapKey] = (TValue)parseValueFn(elementValue);
                    }
                }

                Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
            }

            return(to);
        }
Esempio n. 6
0
        private ParseStringSpanDelegate GetCoreParseStringSpanFn <T>()
        {
            var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);

            if (JsConfig <T> .HasDeserializeFn)
            {
                return(value => JsConfig <T> .ParseFn(Serializer, value.Value()));
            }

            if (type.IsEnum)
            {
                return(x => ParseUtils.TryParseEnum(type, Serializer.UnescapeSafeString(x).Value()));
            }

            if (type == typeof(string))
            {
                return(Serializer.UnescapeStringAsObject);
            }

            if (type == typeof(object))
            {
                return(DeserializeType <TSerializer> .ObjectStringToType);
            }

            var specialParseFn = ParseUtils.GetSpecialParseMethod(type);

            if (specialParseFn != null)
            {
                return(v => specialParseFn(v.Value()));
            }

            if (type.IsArray)
            {
                return(DeserializeArray <T, TSerializer> .ParseStringSpan);
            }

            var builtInMethod = DeserializeBuiltin <T> .ParseStringSpan;

            if (builtInMethod != null)
            {
                return(value => builtInMethod(Serializer.UnescapeSafeString(value)));
            }

            if (type.HasGenericType())
            {
                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IList <>)))
                {
                    return(DeserializeList <T, TSerializer> .ParseStringSpan);
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IDictionary <,>)))
                {
                    return(DeserializeDictionary <TSerializer> .GetParseStringSpanMethod(type));
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(ICollection <>)))
                {
                    return(DeserializeCollection <TSerializer> .GetParseStringSpanMethod(type));
                }

                if (type.HasAnyTypeDefinitionsOf(typeof(Queue <>)) ||
                    type.HasAnyTypeDefinitionsOf(typeof(Stack <>)))
                {
                    return(DeserializeSpecializedCollections <T, TSerializer> .ParseStringSpan);
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(KeyValuePair <,>)))
                {
                    return(DeserializeKeyValuePair <TSerializer> .GetParseStringSpanMethod(type));
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IEnumerable <>)))
                {
                    return(DeserializeEnumerable <T, TSerializer> .ParseStringSpan);
                }

                var customFn = DeserializeCustomGenericType <TSerializer> .GetParseStringSpanMethod(type);

                if (customFn != null)
                {
                    return(customFn);
                }
            }

            var pclParseFn = PclExport.Instance.GetJsReaderParseStringSpanMethod <TSerializer>(typeof(T));

            if (pclParseFn != null)
            {
                return(pclParseFn);
            }

            var isDictionary = typeof(T) != typeof(IEnumerable) && typeof(T) != typeof(ICollection) &&
                               (typeof(T).IsAssignableFrom(typeof(IDictionary)) || typeof(T).HasInterface(typeof(IDictionary)));

            if (isDictionary)
            {
                return(DeserializeDictionary <TSerializer> .GetParseStringSpanMethod(type));
            }

            var isEnumerable = typeof(T).IsAssignableFrom(typeof(IEnumerable)) ||
                               typeof(T).HasInterface(typeof(IEnumerable));

            if (isEnumerable)
            {
                var parseFn = DeserializeSpecializedCollections <T, TSerializer> .ParseStringSpan;
                if (parseFn != null)
                {
                    return(parseFn);
                }
            }

            if (type.IsValueType)
            {
                //at first try to find more faster `ParseStringSpan` method
                var staticParseStringSpanMethod = StaticParseMethod <T> .ParseStringSpan;
                if (staticParseStringSpanMethod != null)
                {
                    return(value => staticParseStringSpanMethod(Serializer.UnescapeSafeString(value)));
                }

                //then try to find `Parse` method
                var staticParseMethod = StaticParseMethod <T> .Parse;
                if (staticParseMethod != null)
                {
                    return(value => staticParseMethod(Serializer.UnescapeSafeString(value).ToString()));
                }
            }
            else
            {
                var staticParseStringSpanMethod = StaticParseRefTypeMethod <TSerializer, T> .ParseStringSpan;
                if (staticParseStringSpanMethod != null)
                {
                    return(value => staticParseStringSpanMethod(Serializer.UnescapeSafeString(value)));
                }

                var staticParseMethod = StaticParseRefTypeMethod <TSerializer, T> .Parse;
                if (staticParseMethod != null)
                {
                    return(value => staticParseMethod(Serializer.UnescapeSafeString(value).ToString()));
                }
            }

            var typeConstructor = DeserializeType <TSerializer> .GetParseStringSpanMethod(TypeConfig <T> .GetState());

            if (typeConstructor != null)
            {
                return(typeConstructor);
            }

            var stringConstructor = DeserializeTypeUtils.GetParseStringSpanMethod(type);

            if (stringConstructor != null)
            {
                return(stringConstructor);
            }

            return(DeserializeType <TSerializer> .ParseAbstractType <T>);
        }
Esempio n. 7
0
        public static IDictionary <TKey, TValue> ParseDictionary <TKey, TValue>(
            ReadOnlySpan <char> value, Type createMapType,
            ParseStringSpanDelegate parseKeyFn, ParseStringSpanDelegate parseValueFn)
        {
            if (value.IsEmpty)
            {
                return(null);
            }

            var to = (createMapType == null)
                ? new Dictionary <TKey, TValue>()
                : (IDictionary <TKey, TValue>)createMapType.CreateInstance();

            var objDeserializer = Json.JsonTypeSerializer.Instance.ObjectDeserializer;

            if (to is Dictionary <string, object> && objDeserializer != null && typeof(TSerializer) == typeof(Json.JsonTypeSerializer))
            {
                return((IDictionary <TKey, TValue>)objDeserializer(value));
            }

            var config = JsConfig.GetConfig();

            var tryToParseItemsAsDictionaries =
                config.ConvertObjectTypesIntoStringDictionary && typeof(TValue) == typeof(object);
            var tryToParseItemsAsPrimitiveTypes =
                config.TryToParsePrimitiveTypeValues && typeof(TValue) == typeof(object);

            var index = VerifyAndGetStartIndex(value, createMapType);

            if (Json.JsonTypeSerializer.IsEmptyMap(value, index))
            {
                return(to);
            }

            var valueLength = value.Length;

            while (index < valueLength)
            {
                var keyValue = Serializer.EatMapKey(value, ref index);
                Serializer.EatMapKeySeperator(value, ref index);
                var elementStartIndex = index;
                var elementValue      = Serializer.EatTypeValue(value, ref index);
                if (keyValue.IsNullOrEmpty())
                {
                    continue;
                }

                TKey mapKey = (TKey)parseKeyFn(keyValue);

                if (tryToParseItemsAsDictionaries)
                {
                    Serializer.EatWhitespace(value, ref elementStartIndex);
                    if (elementStartIndex < valueLength && value[elementStartIndex] == JsWriter.MapStartChar)
                    {
                        var tmpMap = ParseDictionary <TKey, TValue>(elementValue, createMapType, parseKeyFn, parseValueFn);
                        if (tmpMap != null && tmpMap.Count > 0)
                        {
                            to[mapKey] = (TValue)tmpMap;
                        }
                    }
                    else if (elementStartIndex < valueLength && value[elementStartIndex] == JsWriter.ListStartChar)
                    {
                        to[mapKey] = (TValue)DeserializeList <List <object>, TSerializer> .ParseStringSpan(elementValue);
                    }
                    else
                    {
                        to[mapKey] = (TValue)(tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength
                            ? DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value(), value[elementStartIndex])
                            : parseValueFn(elementValue));
                    }
                }
                else
                {
                    if (tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength)
                    {
                        Serializer.EatWhitespace(value, ref elementStartIndex);
                        to[mapKey] = (TValue)DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value(), value[elementStartIndex]);
                    }
                    else
                    {
                        to[mapKey] = (TValue)parseValueFn(elementValue);
                    }
                }

                Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
            }

            return(to);
        }
Esempio n. 8
0
        public ParseStringDelegate GetParseFn <T>()
        {
            var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);

            if (type.IsEnum)
            {
                return(x => Enum.Parse(type, x, true));
            }

            if (type == typeof(string))
            {
                return(Serializer.ParseString);
            }

            if (type == typeof(object))
            {
                return(DeserializeType <TSerializer> .ObjectStringToType);
            }

            var specialParseFn = ParseUtils.GetSpecialParseMethod(type);

            if (specialParseFn != null)
            {
                return(specialParseFn);
            }

            if (type.IsEnum)
            {
                return(x => Enum.Parse(type, x, true));
            }

            if (type.IsArray)
            {
                return(DeserializeArray <T, TSerializer> .Parse);
            }

            var builtInMethod = DeserializeBuiltin <T> .Parse;

            if (builtInMethod != null)
            {
                return(value => builtInMethod(Serializer.ParseRawString(value)));
            }

            if (JsConfig <T> .SerializeFn != null)
            {
                return(value => JsConfig <T> .ParseFn(Serializer.ParseRawString(value)));
            }

            if (type.IsGenericType())
            {
                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IList <>)))
                {
                    return(DeserializeList <T, TSerializer> .Parse);
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IDictionary <,>)))
                {
                    return(DeserializeDictionary <TSerializer> .GetParseMethod(type));
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(ICollection <>)))
                {
                    return(DeserializeCollection <TSerializer> .GetParseMethod(type));
                }

                if (type.HasAnyTypeDefinitionsOf(typeof(Queue <>)) ||
                    type.HasAnyTypeDefinitionsOf(typeof(Stack <>)))
                {
                    return(DeserializeSpecializedCollections <T, TSerializer> .Parse);
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IEnumerable <>)))
                {
                    return(DeserializeEnumerable <T, TSerializer> .Parse);
                }
            }

            var isCollection = typeof(T).IsOrHasGenericInterfaceTypeOf(typeof(ICollection));

            if (isCollection)
            {
                var isDictionary = typeof(T).IsAssignableFrom(typeof(IDictionary)) ||
                                   typeof(T).HasInterface(typeof(IDictionary));
                if (isDictionary)
                {
                    return(DeserializeDictionary <TSerializer> .GetParseMethod(type));
                }

                return(DeserializeEnumerable <T, TSerializer> .Parse);
            }

            var isEnumerable = typeof(T).IsAssignableFrom(typeof(IEnumerable)) ||
                               typeof(T).HasInterface(typeof(IEnumerable));

            if (isEnumerable)
            {
                var parseFn = DeserializeSpecializedCollections <T, TSerializer> .Parse;
                if (parseFn != null)
                {
                    return(parseFn);
                }
            }

            if (type.IsValueType)
            {
                var staticParseMethod = StaticParseMethod <T> .Parse;
                if (staticParseMethod != null)
                {
                    return(value => staticParseMethod(Serializer.ParseRawString(value)));
                }
            }
            else
            {
                var staticParseMethod = StaticParseRefTypeMethod <TSerializer, T> .Parse;
                if (staticParseMethod != null)
                {
                    return(value => staticParseMethod(Serializer.ParseRawString(value)));
                }
            }

            var typeConstructor = DeserializeType <TSerializer> .GetParseMethod(TypeConfig <T> .GetState());

            if (typeConstructor != null)
            {
                return(typeConstructor);
            }

            var stringConstructor = DeserializeTypeUtils.GetParseMethod(type);

            if (stringConstructor != null)
            {
                return(stringConstructor);
            }

            return(DeserializeType <TSerializer> .ParseAbstractType <T>);
        }
Esempio n. 9
0
        private ParseStringDelegate GetCoreParseFn <T>()
        {
            var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);

            if (JsConfig <T> .HasDeserializeFn)
            {
                return(value => JsConfig <T> .ParseFn(Serializer, value));
            }

            if (type.IsEnum())
            {
                return(x => Enum.Parse(type, Serializer.UnescapeSafeString(x), true));
            }

            if (type == typeof(string))
            {
                return(Serializer.UnescapeString);
            }

            if (type == typeof(object))
            {
                return(DeserializeType <TSerializer> .ObjectStringToType);
            }

            var specialParseFn = ParseUtils.GetSpecialParseMethod(type);

            if (specialParseFn != null)
            {
                return(specialParseFn);
            }

            if (type.IsEnum())
            {
                return(x => Enum.Parse(type, x, true));
            }

            if (type.IsArray)
            {
                return(DeserializeArray <T, TSerializer> .Parse);
            }

            var builtInMethod = DeserializeBuiltin <T> .Parse;

            if (builtInMethod != null)
            {
                return(value => builtInMethod(Serializer.UnescapeSafeString(value)));
            }

            if (type.HasGenericType())
            {
                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IList <>)))
                {
                    return(DeserializeList <T, TSerializer> .Parse);
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IDictionary <,>)))
                {
                    return(DeserializeDictionary <TSerializer> .GetParseMethod(type));
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(ICollection <>)))
                {
                    return(DeserializeCollection <TSerializer> .GetParseMethod(type));
                }

                if (type.HasAnyTypeDefinitionsOf(typeof(Queue <>)) ||
                    type.HasAnyTypeDefinitionsOf(typeof(Stack <>)))
                {
                    return(DeserializeSpecializedCollections <T, TSerializer> .Parse);
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(KeyValuePair <,>)))
                {
                    return(DeserializeKeyValuePair <TSerializer> .GetParseMethod(type));
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IEnumerable <>)))
                {
                    return(DeserializeEnumerable <T, TSerializer> .Parse);
                }
            }

#if !NETFX_CORE
#if NET40
            if (typeof(T).IsAssignableFrom(typeof(System.Dynamic.IDynamicMetaObjectProvider)) ||
                typeof(T).HasInterface(typeof(System.Dynamic.IDynamicMetaObjectProvider)))
            {
                return(DeserializeDynamic <TSerializer> .Parse);
            }
#endif
#endif

            var isDictionary = typeof(T) != typeof(IEnumerable) && typeof(T) != typeof(ICollection) &&
                               (typeof(T).AssignableFrom(typeof(IDictionary)) || typeof(T).HasInterface(typeof(IDictionary)));
            if (isDictionary)
            {
                return(DeserializeDictionary <TSerializer> .GetParseMethod(type));
            }

            var isEnumerable = typeof(T).AssignableFrom(typeof(IEnumerable)) ||
                               typeof(T).HasInterface(typeof(IEnumerable));
            if (isEnumerable)
            {
                var parseFn = DeserializeSpecializedCollections <T, TSerializer> .Parse;
                if (parseFn != null)
                {
                    return(parseFn);
                }
            }

            if (type.IsValueType())
            {
                var staticParseMethod = StaticParseMethod <T> .Parse;
                if (staticParseMethod != null)
                {
                    return(value => staticParseMethod(Serializer.UnescapeSafeString(value)));
                }
            }
            else
            {
                var staticParseMethod = StaticParseRefTypeMethod <TSerializer, T> .Parse;
                if (staticParseMethod != null)
                {
                    return(value => staticParseMethod(Serializer.UnescapeSafeString(value)));
                }
            }

            var typeConstructor = DeserializeType <TSerializer> .GetParseMethod(TypeConfig <T> .GetState());

            if (typeConstructor != null)
            {
                return(typeConstructor);
            }

            var stringConstructor = DeserializeTypeUtils.GetParseMethod(type);
            if (stringConstructor != null)
            {
                return(stringConstructor);
            }

            return(DeserializeType <TSerializer> .ParseAbstractType <T>);
        }
Esempio n. 10
0
        public ParseStringDelegate GetParseFn <T>()
        {
            var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);

            if (type.IsEnum)
            {
                return(x => Enum.Parse(type, x, false));
            }

            if (type == typeof(string))
            {
                return(Serializer.ParseString);
            }

            if (type == typeof(object))
            {
                return(x => x);
            }

            var specialParseFn = ParseUtils.GetSpecialParseMethod(type);

            if (specialParseFn != null)
            {
                return(specialParseFn);
            }

            if (type.IsEnum)
            {
                return(x => Enum.Parse(type, x, false));
            }

            if (type.IsArray)
            {
                return(DeserializeArray <T, TSerializer> .Parse);
            }

            var builtInMethod = DeserializeBuiltin <T> .Parse;

            if (builtInMethod != null)
            {
                return(value => builtInMethod(Serializer.ParseRawString(value)));
            }

            if (type.IsGenericType())
            {
                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IList <>)))
                {
                    return(DeserializeList <T, TSerializer> .Parse);
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IDictionary <,>)))
                {
                    return(DeserializeDictionary <TSerializer> .GetParseMethod(type));
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(ICollection <>)))
                {
                    return(DeserializeCollection <TSerializer> .GetParseMethod(type));
                }

                if (type.HasAnyTypeDefinitionsOf(typeof(Queue <>)) ||
                    type.HasAnyTypeDefinitionsOf(typeof(Stack <>)))
                {
                    return(DeserializeSpecializedCollections <T, TSerializer> .Parse);
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IEnumerable <>)))
                {
                    return(DeserializeEnumerable <T, TSerializer> .Parse);
                }
            }

            var staticParseMethod = StaticParseMethod <T> .Parse;

            if (staticParseMethod != null)
            {
                return(value => staticParseMethod(Serializer.ParseRawString(value)));
            }

            var typeConstructor = DeserializeType <TSerializer> .GetParseMethod(type);

            if (typeConstructor != null)
            {
                return(typeConstructor);
            }

            var stringConstructor = DeserializeTypeUtils.GetParseMethod(type);

            if (stringConstructor != null)
            {
                return(stringConstructor);
            }

            return(null);
        }