/// <summary> /// 获取成员转换函数信息 /// </summary> /// <param name="type">成员类型</param> /// <param name="isCustom"></param> /// <returns>成员转换函数信息</returns> internal static MethodInfo GetMemberMethodInfo(Type type, ref bool isCustom) { MethodInfo methodInfo = JsonDeSerializer.GetDeSerializeMethod(type); if (methodInfo != null) { return(methodInfo); } if (type.IsArray) { return(GenericType.Get(type.GetElementType()).JsonDeSerializeArrayMethod.Method); } if (type.IsEnum) { if (type.IsDefined(typeof(FlagsAttribute), false)) { return((EnumGenericType.Get(type).JsonDeSerializeEnumFlagsDelegate).Method); } return((EnumGenericType.Get(type).JsonDeSerializeEnumDelegate).Method); } if (type.IsGenericType) { Type genericType = type.GetGenericTypeDefinition(); if (genericType == typeof(Dictionary <,>)) { return(GenericType2.Get(type.GetGenericArguments()).JsonDeSerializeDictionaryMethod.Method); } if (genericType == typeof(Nullable <>)) { return(GetNullable(type).Method); } if (genericType == typeof(KeyValuePair <,>)) { return(GenericType2.Get(type.GetGenericArguments()).JsonDeSerializeKeyValuePairMethod.Method); } } if ((methodInfo = GetCustom(type)) != null) { isCustom = type.IsValueType; return(methodInfo); } if ((methodInfo = GetIEnumerableConstructor(type)) != null) { return(methodInfo); } if (type.IsValueType) { return(StructGenericType.Get(type).JsonDeSerializeStructMethod); } return(GenericType.Get(type).JsonDeSerializeTypeMethod); }
static TypeDeSerializer() { Type type = typeof(T); MethodInfo methodInfo = JsonDeSerializer.GetDeSerializeMethod(type); if (methodInfo != null) { DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>), methodInfo); return; } if (type.IsArray) { if (type.GetArrayRank() == 1) { DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)GenericType.Get(type.GetElementType()).JsonDeSerializeArrayMethod; } else { DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)GenericType.Get(type).JsonDeSerializeNotSupportDelegate; } return; } if (type.IsEnum) { if (type.IsDefined(typeof(FlagsAttribute), false)) { DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)EnumGenericType.Get(type).JsonDeSerializeEnumFlagsDelegate; } else { DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)EnumGenericType.Get(type).JsonDeSerializeEnumDelegate; } return; } if (type.isSerializeNotSupport()) { DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)GenericType.Get(type).JsonDeSerializeNotSupportDelegate; return; } if (type.IsGenericType) { Type genericType = type.GetGenericTypeDefinition(); if (genericType == typeof(Dictionary <,>)) { DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)GenericType2.Get(type.GetGenericArguments()).JsonDeSerializeDictionaryMethod; return; } if (genericType == typeof(Nullable <>)) { DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)DeSerializeMethodCache.GetNullable(type); return; } if (genericType == typeof(KeyValuePair <,>)) { DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)GenericType2.Get(type.GetGenericArguments()).JsonDeSerializeKeyValuePairMethod; isValueType = true; return; } } if ((methodInfo = DeSerializeMethodCache.GetCustom(type)) != null) { if (type.IsValueType) { #if NOJIT DefaultDeSerializer = new CustomDeSerializer(methodInfo).DeSerialize; #else DynamicMethod dynamicMethod = new DynamicMethod("CustomJsonDeSerializer", null, new Type[] { typeof(JsonDeSerializer), type.MakeByRefType() }, type, true); ILGenerator generator = dynamicMethod.GetILGenerator(); generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldarg_0); generator.call(methodInfo); generator.Emit(OpCodes.Ret); DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)dynamicMethod.CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>)); #endif } else { DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>), methodInfo); } } else { Type attributeType; attribute = type.customAttribute <JsonDeSerializeAttribute>(out attributeType) ?? JsonDeSerializer.AllMemberAttribute; if ((methodInfo = DeSerializeMethodCache.GetIEnumerableConstructor(type)) != null) { DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>), methodInfo); } else { if (type.IsValueType) { isValueType = true; } else if (attribute != JsonDeSerializer.AllMemberAttribute && attributeType != type) { for (Type baseType = type.BaseType; baseType != typeof(object); baseType = baseType.BaseType) { JsonDeSerializeAttribute baseAttribute = baseType.customAttribute <JsonDeSerializeAttribute>(); if (baseAttribute != null) { if (baseAttribute.IsBaseType) { methodInfo = DeSerializeMethodCache.BaseDeSerializeMethod.MakeGenericMethod(baseType, type); DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>), methodInfo); return; } break; } } } FieldIndex defaultMember = null; LeftArray <FieldIndex> fields = DeSerializeMethodCache.GetFields(MemberIndexGroup <T> .GetFields(attribute.MemberFilters), attribute, ref defaultMember); LeftArray <KeyValue <PropertyIndex, MethodInfo> > properties = DeSerializeMethodCache.GetProperties(MemberIndexGroup <T> .GetProperties(attribute.MemberFilters), attribute); bool isBox = false; if (type.IsValueType && fields.Length + properties.Length == 1) { BoxSerializeAttribute boxSerialize = AutoCSer.Metadata.TypeAttribute.GetAttribute <BoxSerializeAttribute>(type); if (boxSerialize != null && boxSerialize.IsJson) { isBox = true; defaultMember = null; } } TryDeSerializeFilter[] deSerializers = new TryDeSerializeFilter[fields.Length + properties.Length + (defaultMember == null ? 0 : 1)]; //memberMap.type memberMapType = memberMap<valueType>.TypeInfo; string[] names = isBox ? null : new string[deSerializers.Length]; #if !NOJIT DeSerializeDynamicMethod dynamicMethod = isBox ? default(DeSerializeDynamicMethod) : new DeSerializeDynamicMethod(type, false), memberMapDynamicMethod = isBox ? default(DeSerializeDynamicMethod) : new DeSerializeDynamicMethod(type, true); #endif int index = 0, nameLength = 0, maxNameLength = 0; foreach (FieldIndex member in fields) { TryDeSerializeFilter tryDeSerialize = deSerializers[index] = new TryDeSerializeFilter { #if NOJIT TryDeSerialize = new FieldDeSerializer(member.Member).DeSerializer(), #else TryDeSerialize = (JsonDeSerializer.DeSerializeDelegate <T>)DeSerializeMethodCache.CreateDynamicMethod(type, member.Member).CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>)), #endif MemberMapIndex = member.MemberIndex, //MemberFilters = member.Member.IsPublic ? Metadata.MemberFilters.PublicInstanceField : Metadata.MemberFilters.NonPublicInstanceField }; if (!isBox) { #if !NOJIT dynamicMethod.Push(member); memberMapDynamicMethod.Push(member); #endif string name = member.AnonymousName; if (name.Length > maxNameLength) { maxNameLength = name.Length; } nameLength += (names[index++] = name).Length; if (member == defaultMember) { deSerializers[deSerializers.Length - 1] = tryDeSerialize; names[deSerializers.Length - 1] = string.Empty; } } } foreach (KeyValue <PropertyIndex, MethodInfo> member in properties) { deSerializers[index] = new TryDeSerializeFilter { #if NOJIT TryDeSerialize = new PropertyDeSerializer(member.Key.Member).DeSerializer(), #else TryDeSerialize = (JsonDeSerializer.DeSerializeDelegate <T>)DeSerializeMethodCache.CreateDynamicMethod(type, member.Key.Member, member.Value).CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>)), #endif MemberMapIndex = member.Key.MemberIndex, //MemberFilters = member.Value.IsPublic ? Metadata.MemberFilters.PublicInstanceProperty : Metadata.MemberFilters.NonPublicInstanceProperty }; if (!isBox) { #if !NOJIT dynamicMethod.Push(member.Key, member.Value); memberMapDynamicMethod.Push(member.Key, member.Value); #endif if (member.Key.Member.Name.Length > maxNameLength) { maxNameLength = member.Key.Member.Name.Length; } nameLength += (names[index++] = member.Key.Member.Name).Length; } } if (isBox) { unboxDeSerializer = deSerializers[0].TryDeSerialize; DefaultDeSerializer = unbox; } else { #if !NOJIT deSerializeMember = (DeSerializeMember)dynamicMethod.Create <DeSerializeMember>(); deSerializeMemberMap = (DeSerializeMemberMap)memberMapDynamicMethod.Create <DeSerializeMemberMap>(); #endif if (type.Name[0] == '<') { isAnonymousType = true; } if (maxNameLength > (short.MaxValue >> 1) - 4 || nameLength == 0) { memberNames = Unmanaged.NullByte8; } else { memberNames = Unmanaged.GetStaticPointer((nameLength + (names.Length - (defaultMember == null ? 0 : 1)) * 5 + 1) << 1, false); byte *write = memberNames.Byte; foreach (string name in names) { if (name.Length != 0) { if (write == memberNames.Byte) { *(short *)write = (short)((name.Length + 3) * sizeof(char)); *(char *)(write + sizeof(short)) = '"'; write += sizeof(short) + sizeof(char); } else { *(short *)write = (short)((name.Length + 4) * sizeof(char)); *(int *)(write + sizeof(short)) = ',' + ('"' << 16); write += sizeof(short) + sizeof(int); } fixed(char *nameFixed = name) AutoCSer.Extensions.StringExtension.SimpleCopyNotNull(nameFixed, (char *)write, name.Length); *(int *)(write += name.Length << 1) = '"' + (':' << 16); write += sizeof(int); } } *(short *)write = 0; } memberSearcher = new StateSearcher(StateSearcher.GetMemberSearcher(type, names)); memberDeSerializers = deSerializers; Type refType = type.MakeByRefType(); foreach (AutoCSer.Metadata.AttributeMethod attributeMethod in AutoCSer.Metadata.AttributeMethod.GetStatic(type)) { if ((methodInfo = attributeMethod.Method).ReturnType == typeof(void)) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 3 && parameters[0].ParameterType == typeof(JsonDeSerializer) && parameters[1].ParameterType == refType && parameters[2].ParameterType == Emit.Pub.PointerSizeRefType) { if (attributeMethod.GetAttribute <JsonDeSerializeUnknownNameAttriubte>() != null) { onUnknownName = (UnknownDeSerialize)Delegate.CreateDelegate(typeof(UnknownDeSerialize), methodInfo); break; } } } } } } } }