public static IDictionary ParseIDictionary(ReadOnlySpan <char> value, Type dictType) { if (value.IsEmpty) { return(null); } var index = VerifyAndGetStartIndex(value, dictType); var valueParseMethod = Serializer.GetParseStringSpanFn(typeof(object)); if (valueParseMethod == null) { return(null); } var to = ActivatorUtils.FastCreateInstance <IDictionary>(dictType); 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.IsEmpty) { continue; } var mapKey = valueParseMethod(keyValue); if (elementStartIndex < valueLength) { Serializer.EatWhitespace(value, ref elementStartIndex); to[mapKey] = DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value(), value[elementStartIndex]); } else { to[mapKey] = valueParseMethod(elementValue); } Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } return(to); }
public static object ConvertFromCollection(object enumerable) { //var to = (ICollection<T>)typeof(TCollection).CreateInstance(); var to = ActivatorUtils.FastCreateInstance <ICollection <T> >(typeof(TCollection)); var from = (IEnumerable <T>)enumerable; foreach (var item in from) { to.Add(item); } return(to); }
internal static object GetFormatter(Type t) { #if !TEST40 if (typeof(ITestMessage).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo())) #else if (typeof(ITestMessage).IsAssignableFrom(t)) #endif { return(ActivatorUtils.FastCreateInstance(typeof(TestMessageFormatter <>).GetCachedGenericType(t))); } return(null); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <Type, ValueSerializer> typeMapping) { var preserveObjectReferences = serializer.Options.PreserveObjectReferences; var ser = new ObjectSerializer(type); typeMapping.TryAdd(type, ser); var elementSerializer = serializer.GetSerializerByType(typeof(DictionaryEntry)); ObjectReader reader = (stream, session) => { var instance = ActivatorUtils.FastCreateInstance(type) as IDictionary <string, object>; if (preserveObjectReferences) { session.TrackDeserializedObject(instance); } var count = stream.ReadInt32(session); for (var i = 0; i < count; i++) { var entry = (KeyValuePair <string, object>)stream.ReadObject(session); instance.Add(entry); } return(instance); }; ObjectWriter writer = (stream, obj, session) => { if (preserveObjectReferences) { session.TrackSerializedObject(obj); } var dict = obj as IDictionary <string, object>; // ReSharper disable once PossibleNullReferenceException Int32Serializer.WriteValueImpl(stream, dict.Count, session); foreach (var item in dict) { stream.WriteObject(item, typeof(DictionaryEntry), elementSerializer, serializer.Options.PreserveObjectReferences, session); // elementSerializer.WriteValue(stream,item,session); } }; ser.Initialize(reader, writer); return(ser); }
static FormatterCache() { Interlocked.CompareExchange(ref s_isFreezed, Locked, Unlocked); var formatters = Volatile.Read(ref s_formatters); foreach (var item in formatters) { foreach (var implInterface in item.GetType().GetTypeInfo().ImplementedInterfaces) { #if NET40 if (implInterface.IsGenericType && implInterface.GenericTypeArguments()[0] == typeof(T)) #else if (implInterface.IsGenericType && implInterface.GenericTypeArguments[0] == typeof(T)) #endif { Formatter = (IMessagePackFormatter <T>)item; return; } } } var resolvers = Volatile.Read(ref s_resolvers); foreach (var item in resolvers) { var f = item.GetFormatter <T>(); if (f != null) { Formatter = f; return; } } { var f = MessagePackStandardResolver.TypelessObjectResolver.GetFormatter <T>(); if (f != null) { Formatter = f; return; } } Formatter = ActivatorUtils.FastCreateInstance <IMessagePackFormatter <T> >(typeof(DynamicProxyFormatter <>).GetCachedGenericType(typeof(T))); }
object CreateInstance(ProtoReader source, bool includeLocalCallback) { //Helpers.DebugWriteLine("* creating : " + forType.FullName); object obj; if (factory != null) { obj = InvokeCallback(factory, null, source.Context); } else if (useConstructor) { if (!hasConstructor) { TypeModel.ThrowCannotCreateInstance(constructType); } // ## 苦竹 修改 ## // obj = Activator.CreateInstance(constructType //#if !(CF || SILVERLIGHT || WINRT || PORTABLE || NETSTANDARD1_3 || NETSTANDARD1_4) // , nonPublic: true //#endif // ); obj = ActivatorUtils.FastCreateInstance(constructType); } else { obj = BclHelpers.GetUninitializedObject(constructType); } ProtoReader.NoteObject(obj, source); if (baseCtorCallbacks != null) { for (int i = 0; i < baseCtorCallbacks.Length; i++) { InvokeCallback(baseCtorCallbacks[i], obj, source.Context); } } if (includeLocalCallback && callbacks != null) { InvokeCallback(callbacks.BeforeDeserialize, obj, source.Context); } return(obj); }
public override object Read(object untyped, ProtoReader source) { TDictionary typed = AppendToCollection ? ((TDictionary)untyped) : null; //if (typed == null) typed = (TDictionary)Activator.CreateInstance(concreteType); if (typed == null) { typed = (TDictionary)ActivatorUtils.FastCreateInstance(concreteType); } do { var key = DefaultKey; var value = DefaultValue; SubItemToken token = ProtoReader.StartSubItem(source); int field; while ((field = source.ReadFieldHeader()) > 0) { switch (field) { case 1: key = (TKey)keyTail.Read(null, source); break; case 2: value = (TValue)Tail.Read(Tail.RequiresOldValue ? (object)value : null, source); break; default: source.SkipField(); break; } } ProtoReader.EndSubItem(token, source); typed[key] = value; } while (source.TryReadFieldHeader(fieldNumber)); return(typed); }
public static object ParseTuple(Type tupleType, StringSegment value) { var index = 0; Serializer.EatMapStartChar(value, ref index); if (JsonTypeSerializer.IsEmptyMap(value, index)) { //return tupleType.CreateInstance(); return(ActivatorUtils.FastCreateInstance(tupleType)); } var genericArgs = tupleType.GetGenericArguments(); var argValues = new object[genericArgs.Length]; 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); if (!keyValue.HasValue) { continue; } var keyIndex = keyValue.Substring("Item".Length).ToInt() - 1; var parseFn = Serializer.GetParseStringSegmentFn(genericArgs[keyIndex]); argValues[keyIndex] = parseFn(elementValue); Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } var ctor = tupleType.GetConstructors() .First(x => x.GetParameters().Length == genericArgs.Length); return(ctor.Invoke(argValues)); }
public static ICollection <T> CreateAndPopulate <T>(Type ofCollectionType, T[] withItems) { if (withItems == null) { return(null); } if (ofCollectionType == null) { return(new List <T>(withItems)); } var genericType = ofCollectionType.FirstGenericType(); var genericTypeDefinition = genericType != null ? genericType.GetGenericTypeDefinition() : null; if (genericTypeDefinition == typeof(HashSet <>)) { return(new HashSet <T>(withItems)); } if (genericTypeDefinition == typeof(LinkedList <>)) { return(new LinkedList <T>(withItems)); } //var collection = (ICollection<T>)ofCollectionType.CreateInstance(); var collection = ActivatorUtils.FastCreateInstance <ICollection <T> >(ofCollectionType); foreach (var item in withItems) { collection.Add(item); } return(collection); }
public static Expression GetNewExpression(Type type) { if (type.IsValueType) { var x = Expression.Constant(ActivatorUtils.FastCreateInstance(type)); var convert = Expression.Convert(x, typeof(object)); return(convert); } //#if SERIALIZATION var defaultCtor = type.GetConstructor(new Type[] { }); var il = defaultCtor?.GetMethodBody()?.GetILAsByteArray(); var sideEffectFreeCtor = il != null && il.Length <= 8; //this is the size of an empty ctor if (sideEffectFreeCtor) { //the ctor exists and the size is empty. lets use the New operator return(Expression.New(defaultCtor)); } //#endif var emptyObjectMethod = typeof(TypeEx).GetMethod(nameof(TypeEx.GetEmptyObject)); var emptyObject = Expression.Call(null, emptyObjectMethod, type.ToConstant()); return(emptyObject); }
internal static object StringToType( TypeConfig typeConfig, StringSegment strType, EmptyCtorDelegate ctorFn, Dictionary <HashedStringSegment, TypeAccessor> typeAccessorMap) { var index = 0; var type = typeConfig.Type; if (!strType.HasValue) { return(null); } var buffer = strType.Buffer; var offset = strType.Offset; var strTypeLength = strType.Length; //if (!Serializer.EatMapStartChar(strType, ref index)) for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) { break; } } //Whitespace inline if (buffer[offset + index] != JsWriter.MapStartChar) { throw DeserializeTypeRef.CreateSerializationError(type, strType.Value); } index++; if (JsonTypeSerializer.IsEmptyMap(strType, index)) { return(ctorFn()); } object instance = null; var propertyResolver = JsConfig.PropertyConvention == PropertyConvention.Lenient ? ParseUtils.LenientPropertyNameResolver : ParseUtils.DefaultPropertyNameResolver; while (index < strTypeLength) { var propertyName = JsonTypeSerializer.ParseJsonString(strType, ref index); //Serializer.EatMapKeySeperator(strType, ref index); for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) { break; } } //Whitespace inline if (strTypeLength != index) { index++; } var propertyValueStr = Serializer.EatValue(strType, ref index); var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1; //if we already have an instance don't check type info, because then we will have a half deserialized object //we could throw here or just use the existing instance. if (instance == null && possibleTypeInfo && propertyName == typeAttr) { var explicitTypeName = Serializer.ParseString(propertyValueStr); var explicitType = JsConfig.TypeFinder(explicitTypeName); if (explicitType == null || explicitType.IsInterface || explicitType.IsAbstract) { Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr); } else if (!type.IsAssignableFrom(explicitType)) { Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr); } else { JsWriter.AssertAllowedRuntimeType(explicitType); //instance = explicitType.CreateInstance(); instance = ActivatorUtils.FastCreateInstance(explicitType); } if (instance != null) { //If __type info doesn't match, ignore it. if (!type.IsInstanceOfType(instance)) { instance = null; } else { var derivedType = instance.GetType(); if (derivedType != type) { var derivedTypeConfig = new TypeConfig(derivedType); var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer); if (map != null) { typeAccessorMap = map; } } } } Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); continue; } if (instance == null) { instance = ctorFn(); } var typeAccessor = propertyResolver.GetTypeAccessorForProperty(propertyName, typeAccessorMap); var propType = possibleTypeInfo && propertyValueStr.GetChar(0) == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null; if (propType != null) { try { if (typeAccessor != null) { //var parseFn = Serializer.GetParseFn(propType); var parseFn = JsonReader.GetParseStringSegmentFn(propType); var propertyValue = parseFn(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName.Value, propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) { break; } } //Whitespace inline if (index != strTypeLength) { var success = buffer[offset + index] == JsWriter.ItemSeperator || buffer[offset + index] == JsWriter.MapEndChar; index++; if (success) { for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) { break; } } //Whitespace inline } } continue; } catch (Exception e) { if (JsConfig.OnDeserializationError != null) { JsConfig.OnDeserializationError(instance, propType, propertyName.Value, propertyValueStr.Value, e); } if (JsConfig.ThrowOnError) { throw DeserializeTypeRef.GetSerializationException(propertyName.Value, propertyValueStr.Value, propType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName, propertyValueStr.Value); } } } if (typeAccessor?.GetProperty != null && typeAccessor.SetProperty != null) { try { var propertyValue = typeAccessor.GetProperty(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName.Value, propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } catch (NotSupportedException) { throw; } catch (Exception e) { if (JsConfig.OnDeserializationError != null) { JsConfig.OnDeserializationError(instance, propType ?? typeAccessor.PropertyType, propertyName.Value, propertyValueStr.Value, e); } if (JsConfig.ThrowOnError) { throw DeserializeTypeRef.GetSerializationException(propertyName.Value, propertyValueStr.Value, typeAccessor.PropertyType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName, propertyValueStr.Value); } } } else { // the property is not known by the DTO typeConfig.OnDeserializing?.Invoke(instance, propertyName.Value, propertyValueStr.Value); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) { break; } } //Whitespace inline if (index != strType.Length) { var success = buffer[offset + index] == JsWriter.ItemSeperator || buffer[offset + index] == JsWriter.MapEndChar; index++; if (success) { for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) { break; } } //Whitespace inline } } } return(instance); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <Type, ValueSerializer> typeMapping) { var exceptionSerializer = new ObjectSerializer(type); exceptionSerializer.Initialize((stream, session) => { var exception = ActivatorUtils.FastCreateInstance(type); var sessionSerializer = session.Serializer; if (sessionSerializer.Options.PreserveObjectReferences) { session.TrackDeserializedObject(exception); } var fields = s_filedCache.GetOrAdd(type, s_getFieldsFunc); foreach (var(field, getter, setter) in fields) { var fieldType = field.FieldType; object fieldValue; if (!sessionSerializer.Options.VersionTolerance && fieldType.IsHyperionPrimitive()) { var valueSerializer = sessionSerializer.GetSerializerByType(fieldType); fieldValue = valueSerializer.ReadValue(stream, session); } else { var valueType = fieldType; if (fieldType.IsNullableType()) { valueType = Nullable.GetUnderlyingType(fieldType); } var valueSerializer = sessionSerializer.GetSerializerByType(valueType); fieldValue = stream.ReadObject(session); } setter(exception, fieldValue); } return(exception); }, (stream, exception, session) => { var sessionSerializer = session.Serializer; if (sessionSerializer.Options.PreserveObjectReferences) { session.TrackSerializedObject(exception); } var fields = s_filedCache.GetOrAdd(type, s_getFieldsFunc); foreach (var(field, getter, setter) in fields) { var fieldType = field.FieldType; var v = getter(exception); //if the type is one of our special primitives, ignore manifest as the content will always only be of this type if (!sessionSerializer.Options.VersionTolerance && fieldType.IsHyperionPrimitive()) { var valueSerializer = sessionSerializer.GetSerializerByType(fieldType); valueSerializer.WriteValue(stream, v, session); } else { var valueType = fieldType; if (fieldType.IsNullableType()) { valueType = Nullable.GetUnderlyingType(fieldType); } var valueSerializer = sessionSerializer.GetSerializerByType(valueType); stream.WriteObject(v, valueType, valueSerializer, true, session); } } }); typeMapping.TryAdd(type, exceptionSerializer); return(exceptionSerializer); }
internal static object StringToType(ReadOnlySpan <char> strType, TypeConfig typeConfig, EmptyCtorDelegate ctorFn, KeyValuePair <string, TypeAccessor>[] typeAccessors) { var index = 0; var type = typeConfig.Type; if (strType.IsEmpty) { return(null); } //if (!Serializer.EatMapStartChar(strType, ref index)) if (strType[index++] != JsWriter.MapStartChar) { throw DeserializeTypeRef.CreateSerializationError(type, strType.ToString()); } if (JsonTypeSerializer.IsEmptyMap(strType)) { return(ctorFn()); } var config = JsConfig.GetConfig(); object instance = null; var lenient = config.PropertyConvention == PropertyConvention.Lenient; var strTypeLength = strType.Length; while (index < strTypeLength) { var propertyName = Serializer.EatMapKey(strType, ref index).Trim(); //Serializer.EatMapKeySeperator(strType, ref index); index++; var propertyValueStr = Serializer.EatValue(strType, ref index); var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1; if (possibleTypeInfo && propertyName.Equals(typeAttr.Span, StringComparison.OrdinalIgnoreCase)) { var explicitTypeName = Serializer.ParseString(propertyValueStr); var explicitType = config.TypeFinder(explicitTypeName); if (explicitType == null || explicitType.IsInterface || explicitType.IsAbstract) { Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr.ToString()); } else if (!type.IsAssignableFrom(explicitType)) { Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr.ToString()); } else { JsWriter.AssertAllowedRuntimeType(explicitType); instance = ActivatorUtils.FastCreateInstance(explicitType); } if (instance != null) { //If __type info doesn't match, ignore it. if (!type.IsInstanceOfType(instance)) { instance = null; } else { var derivedType = instance.GetType(); if (derivedType != type) { var map = DeserializeTypeRef.GetCachedTypeAccessors(derivedType, Serializer); if (map != null) { typeAccessors = map; } } } } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } continue; } if (instance == null) { instance = ctorFn(); } var typeAccessor = typeAccessors.Get(propertyName, lenient); var propType = possibleTypeInfo && propertyValueStr[0] == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null; if (propType != null) { try { if (typeAccessor != null) { var parseFn = Serializer.GetParseStringSpanFn(propType); var propertyValue = parseFn(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName.ToString(), propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } continue; } catch (Exception e) { config.OnDeserializationError?.Invoke(instance, propType, propertyName.ToString(), propertyValueStr.ToString(), e); if (config.ThrowOnError) { throw DeserializeTypeRef.GetSerializationException(propertyName.ToString(), propertyValueStr.ToString(), propType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName.ToString(), propertyValueStr.ToString()); } } } if (typeAccessor?.GetProperty != null && typeAccessor.SetProperty != null) { try { var propertyValue = typeAccessor.GetProperty(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName.ToString(), propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } catch (NotSupportedException) { throw; } catch (Exception e) { config.OnDeserializationError?.Invoke(instance, propType ?? typeAccessor.PropertyType, propertyName.ToString(), propertyValueStr.ToString(), e); if (config.ThrowOnError) { throw DeserializeTypeRef.GetSerializationException(propertyName.ToString(), propertyValueStr.ToString(), propType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName.ToString(), propertyValueStr.ToString()); } } } else { // the property is not known by the DTO typeConfig.OnDeserializing?.Invoke(instance, propertyName.ToString(), propertyValueStr.ToString()); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } } return(instance); }
static object CreateInstance(Type genericType, params Type[] genericTypeArguments) { return(ActivatorUtils.FastCreateInstance(genericType.GetCachedGenericType(genericTypeArguments))); }
//public static bool IsHyperionPrimitive(this Type type) //{ // return type == Int32Type || // type == Int64Type || // type == Int16Type || // type == UInt32Type || // type == UInt64Type || // type == UInt16Type || // type == ByteType || // type == SByteType || // type == DateTimeType || // type == BoolType || // type == StringType || // type == GuidType || // type == CombGuidType || // type == FloatType || // type == DoubleType || // type == DecimalType || // type == CharType; // //add TypeSerializer with null support //} //#if !SERIALIZATION // //HACK: the GetUnitializedObject actually exists in .NET Core, its just not public // private static readonly Func<Type, object> getUninitializedObjectDelegate = (Func<Type, object>) // typeof(string) // .GetTypeInfo() // .Assembly // .GetType("System.Runtime.Serialization.FormatterServices") // ?.GetTypeInfo() // ?.GetMethod("GetUninitializedObject", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static) // ?.CreateDelegate(typeof(Func<Type, object>)); // public static object GetEmptyObject(this Type type) // { // return getUninitializedObjectDelegate(type); // } //#else public static object GetEmptyObject(this Type type) { //return FormatterServices.GetUninitializedObject(type); return(ActivatorUtils.FastCreateInstance(type)); }
// Reduce IL2CPP code generate size(don't write long code in <T>) internal static object GetFormatter(Type t) { var ti = t.GetTypeInfo(); if (t.IsArray) { var rank = t.GetArrayRank(); if (rank == 1) { if (t.GetElementType() == typeof(byte)) // byte[] is also supported in builtin formatter. { return(ByteArrayFormatter.Instance); } return(ActivatorUtils.FastCreateInstance(typeof(ArrayFormatter <>).GetCachedGenericType(t.GetElementType()))); } else if (rank == 2) { return(ActivatorUtils.FastCreateInstance(typeof(TwoDimentionalArrayFormatter <>).GetCachedGenericType(t.GetElementType()))); } else if (rank == 3) { return(ActivatorUtils.FastCreateInstance(typeof(ThreeDimentionalArrayFormatter <>).GetCachedGenericType(t.GetElementType()))); } else if (rank == 4) { return(ActivatorUtils.FastCreateInstance(typeof(FourDimentionalArrayFormatter <>).GetCachedGenericType(t.GetElementType()))); } else { return(null); // not supported built-in } } else if (t.IsGenericType) { var genericType = t.GetGenericTypeDefinition(); var isNullable = genericType.IsNullable(); var genericTypeArguments = t.GenericTypeArguments; var nullableElementType = isNullable ? genericTypeArguments[0] : null; const string _systemTupleType = "System.Tuple"; const string _systemValueTupleType = "System.ValueTuple"; if (genericType == typeof(KeyValuePair <,>)) { return(CreateInstance(typeof(KeyValuePairFormatter <,>), genericTypeArguments)); } else if (isNullable && nullableElementType.IsConstructedGenericType && nullableElementType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)) { return(CreateInstance(typeof(NullableFormatter <>), new[] { nullableElementType })); } // ValueTask else if (genericType == typeof(ValueTask <>)) { return(CreateInstance(typeof(ValueTaskFormatter <>), genericTypeArguments)); } else if (isNullable && nullableElementType.IsConstructedGenericType && nullableElementType.GetGenericTypeDefinition() == typeof(ValueTask <>)) { return(CreateInstance(typeof(NullableFormatter <>), new[] { nullableElementType })); } // Tuple else if (t.FullName.StartsWith(_systemTupleType, StringComparison.Ordinal)) { Type tupleFormatterType = null; switch (genericTypeArguments.Length) { case 1: tupleFormatterType = typeof(TupleFormatter <>); break; case 2: tupleFormatterType = typeof(TupleFormatter <,>); break; case 3: tupleFormatterType = typeof(TupleFormatter <, ,>); break; case 4: tupleFormatterType = typeof(TupleFormatter <, , ,>); break; case 5: tupleFormatterType = typeof(TupleFormatter <, , , ,>); break; case 6: tupleFormatterType = typeof(TupleFormatter <, , , , ,>); break; case 7: tupleFormatterType = typeof(TupleFormatter <, , , , , ,>); break; case 8: tupleFormatterType = typeof(TupleFormatter <, , , , , , ,>); break; default: break; } return(CreateInstance(tupleFormatterType, genericTypeArguments)); } // ValueTuple else if (t.FullName.StartsWith(_systemValueTupleType, StringComparison.Ordinal)) { Type tupleFormatterType = null; switch (genericTypeArguments.Length) { case 1: tupleFormatterType = typeof(ValueTupleFormatter <>); break; case 2: tupleFormatterType = typeof(ValueTupleFormatter <,>); break; case 3: tupleFormatterType = typeof(ValueTupleFormatter <, ,>); break; case 4: tupleFormatterType = typeof(ValueTupleFormatter <, , ,>); break; case 5: tupleFormatterType = typeof(ValueTupleFormatter <, , , ,>); break; case 6: tupleFormatterType = typeof(ValueTupleFormatter <, , , , ,>); break; case 7: tupleFormatterType = typeof(ValueTupleFormatter <, , , , , ,>); break; case 8: tupleFormatterType = typeof(ValueTupleFormatter <, , , , , , ,>); break; default: break; } return(CreateInstance(tupleFormatterType, genericTypeArguments)); } // ArraySegement else if (genericType == typeof(ArraySegment <>)) { if (genericTypeArguments[0] == typeof(byte)) { return(ByteArraySegmentFormatter.Instance); } else { return(CreateInstance(typeof(ArraySegmentFormatter <>), genericTypeArguments)); } } else if (isNullable && nullableElementType.IsConstructedGenericType && nullableElementType.GetGenericTypeDefinition() == typeof(ArraySegment <>)) { if (nullableElementType == typeof(ArraySegment <byte>)) { return(new StaticNullableFormatter <ArraySegment <byte> >(ByteArraySegmentFormatter.Instance)); } else { return(CreateInstance(typeof(NullableFormatter <>), new[] { nullableElementType })); } } // Mapped formatter else { Type formatterType; if (formatterMap.TryGetValue(genericType, out formatterType)) { return(CreateInstance(formatterType, genericTypeArguments)); } // generic collection else if (genericTypeArguments.Length == 1 && ti.ImplementedInterfaces.Any(x => x.IsConstructedGenericType && x.GetGenericTypeDefinition() == typeof(ICollection <>)) && ti.DeclaredConstructors.Any(x => 0u >= (uint)x.GetParameters().Length)) { var elemType = genericTypeArguments[0]; return(CreateInstance(typeof(GenericCollectionFormatter <,>), new[] { elemType, t })); } // generic dictionary else if (genericTypeArguments.Length == 2 && ti.ImplementedInterfaces.Any(x => x.IsConstructedGenericType && x.GetGenericTypeDefinition() == typeof(IDictionary <,>)) && ti.DeclaredConstructors.Any(x => 0u >= (uint)x.GetParameters().Length)) { var keyType = genericTypeArguments[0]; var valueType = genericTypeArguments[1]; return(CreateInstance(typeof(GenericDictionaryFormatter <, ,>), new[] { keyType, valueType, t })); } if (typeof(Delegate).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(DelegateFormatter <>).GetCachedGenericType(t))); } if (typeof(Exception).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(SimpleExceptionFormatter <>).GetCachedGenericType(t))); } if (typeof(Expression).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(SimpleExpressionFormatter <>).GetCachedGenericType(t))); } if (typeof(SymbolDocumentInfo).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(SymbolDocumentInfoFormatter <>).GetCachedGenericType(t))); } if (typeof(MemberBinding).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(MemberBindingFormatter <>).GetCachedGenericType(t))); } } } else { // NonGeneric Collection if (t == typeof(IList)) { return(NonGenericInterfaceListFormatter.Instance); } else if (t == typeof(IDictionary)) { return(NonGenericInterfaceDictionaryFormatter.Instance); } if (typeof(IList).IsAssignableFrom(t) && ti.DeclaredConstructors.Any(x => 0u >= (uint)x.GetParameters().Length)) { return(ActivatorUtils.FastCreateInstance(typeof(NonGenericListFormatter <>).GetCachedGenericType(t))); } else if (typeof(IDictionary).IsAssignableFrom(t) && ti.DeclaredConstructors.Any(x => 0u >= (uint)x.GetParameters().Length)) { return(ActivatorUtils.FastCreateInstance(typeof(NonGenericDictionaryFormatter <>).GetCachedGenericType(t))); } if (typeof(Type).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(SimpleTypeFormatter <>).GetCachedGenericType(t))); } if (typeof(ConstructorInfo).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(ConstructorInfoFormatter <>).GetCachedGenericType(t))); } if (typeof(EventInfo).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(EventInfoFormatter <>).GetCachedGenericType(t))); } if (typeof(FieldInfo).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(FieldInfoFormatter <>).GetCachedGenericType(t))); } if (typeof(PropertyInfo).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(PropertyInfoFormatter <>).GetCachedGenericType(t))); } if (typeof(MethodInfo).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(MethodInfoFormatter <>).GetCachedGenericType(t))); } if (typeof(MemberInfo).IsAssignableFrom(t)) // 是否无用 { return(ActivatorUtils.FastCreateInstance(typeof(MemberInfoFormatter <>).GetCachedGenericType(t))); } if (typeof(Delegate).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(DelegateFormatter <>).GetCachedGenericType(t))); } if (typeof(Exception).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(SimpleExceptionFormatter <>).GetCachedGenericType(t))); } if (typeof(Expression).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(SimpleExpressionFormatter <>).GetCachedGenericType(t))); } if (typeof(SymbolDocumentInfo).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(SymbolDocumentInfoFormatter <>).GetCachedGenericType(t))); } if (typeof(MemberBinding).IsAssignableFrom(t)) { return(ActivatorUtils.FastCreateInstance(typeof(MemberBindingFormatter <>).GetCachedGenericType(t))); } } return(null); }
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>() : ActivatorUtils.FastCreateInstance <IDictionary <TKey, TValue> >(createMapType); //(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; } TKey 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); }
public static T ConvertTo <T>(this object from) { if (from == null) { return(default(T)); } var fromType = from.GetType(); if (fromType == typeof(T)) { return((T)from); } if (fromType.IsValueType || typeof(T).IsValueType) { if (!fromType.IsEnum && !typeof(T).IsEnum) { if (typeof(T) == typeof(char) && from is string s) { return((T)(s.Length > 0 ? (object)s[0] : null)); } if (typeof(T) == typeof(string) && from is char c) { return((T)(object)c.ToString()); } var destNumberType = DynamicNumber.GetNumber(typeof(T)); var value = destNumberType?.ConvertFrom(from); if (value != null) { if (typeof(T) == typeof(char)) { return((T)(object)value.ToString()[0]); } return((T)value); } if (typeof(T) == typeof(string)) { var srcNumberType = DynamicNumber.GetNumber(from.GetType()); if (srcNumberType != null) { return((T)(object)srcNumberType.ToString(from)); } } } return((T)ChangeValueType(from, typeof(T))); } if (typeof(IEnumerable).IsAssignableFrom(typeof(T))) { var listResult = TranslateListWithElements.TryTranslateCollections( fromType, typeof(T), from); return((T)listResult); } var to = ActivatorUtils.FastCreateInstance <T>();// typeof(T).CreateInstance<T>(); return(to.PopulateWith(from)); }