public bool TryGetSerializableMemberDetails(string name, out MemberDetail property) { if (membersFieldBackedByName == null) { lock (this) { if (membersFieldBackedByName == null) { membersFieldBackedByName = MemberDetails.ToDictionary(x => x.Name); } } } return(this.membersFieldBackedByName.TryGetValue(name, out property)); }
public bool TryGetMemberCaseInsensitive(string name, out MemberDetail member) { if (membersByNameLower == null) { lock (this) { if (membersByNameLower == null) { this.membersByNameLower = this.MemberDetails.GroupBy(x => x.Name.ToLower()).Where(x => x.Count() == 1).ToDictionary(x => x.Key, x => x.First()); } } } return(this.membersByNameLower.TryGetValue(name.ToLower(), out member)); }
internal MemberDetail(MemberInfo member, MemberDetail backingFieldDetail) { this.BackingFieldDetail = backingFieldDetail; this.MemberInfo = member; this.Name = member.Name; if (MemberInfo.MemberType == MemberTypes.Property) { var property = (PropertyInfo)MemberInfo; this.Type = property.PropertyType; } else if (MemberInfo.MemberType == MemberTypes.Field) { var field = (FieldInfo)MemberInfo; this.Type = field.FieldType; } this.IsBacked = member.MemberType == MemberTypes.Field || backingFieldDetail != null; }
internal TypeDetail(Type type) { this.Type = type; this.Interfaces = type.GetInterfaces(); var baseType = type; var baseTypes = new List <Type>(); while (baseType != null) { baseTypes.Add(baseType); baseType = baseType.BaseType; } this.BaseTypes = baseTypes; this.IsNullable = type.Name == nullaleTypeName; this.IsIEnumerable = !TypeLookup.CoreTypes.Contains(type) && (type.IsArray || type.Name == enumberableTypeName || Interfaces.Select(x => x.Name).Contains(enumberableTypeName)); this.IsICollection = !TypeLookup.CoreTypes.Contains(type) && (type.Name == collectionTypeName || Interfaces.Select(x => x.Name).Contains(collectionTypeName)); this.IsICollectionGeneric = !TypeLookup.CoreTypes.Contains(type) && (type.Name == collectionGenericTypeName || Interfaces.Select(x => x.Name).Contains(collectionGenericTypeName)); this.IsIList = !TypeLookup.CoreTypes.Contains(type) && (type.Name == listTypeName || type.Name == listGenericTypeName || Interfaces.Select(x => x.Name).Contains(listTypeName) || Interfaces.Select(x => x.Name).Contains(listGenericTypeName)); this.IsISet = !TypeLookup.CoreTypes.Contains(type) && (type.Name == setGenericTypeName || Interfaces.Select(x => x.Name).Contains(setGenericTypeName)); if (this.IsIEnumerable) { if (type.Name == enumberableGenericTypeName) { this.IsIEnumerableGeneric = true; this.IEnumerableGenericInnerType = type.GetGenericArguments()[0]; } else { var enumerableGeneric = Interfaces.Where(x => x.Name == enumberableGenericTypeName).ToArray(); if (enumerableGeneric.Length == 1) { this.IsIEnumerableGeneric = true; this.IEnumerableGenericInnerType = enumerableGeneric[0].GetGenericArguments()[0]; } } } if (type.IsGenericType) { this.InnerTypes = type.GetGenericArguments(); } else if (type.IsArray) { this.InnerTypes = new Type[] { type.GetElementType() } } ; else { this.InnerTypes = Type.EmptyTypes; } if (TypeLookup.CoreTypeLookup(type, out CoreType coreTypeLookup)) { this.CoreType = coreTypeLookup; } if (TypeLookup.SpecialTypeLookup(type, out SpecialType specialTypeLookup)) { this.SpecialType = specialTypeLookup; switch (specialTypeLookup) { case Reflection.SpecialType.Task: this.IsTask = true; break; case Reflection.SpecialType.Dictionary: var innerType = TypeAnalyzer.GetGenericType(keyValuePairType, (Type[])this.InnerTypes); this.InnerTypes = new Type[] { innerType }; break; } } if (type.IsEnum) { var enumEnderlyingType = Enum.GetUnderlyingType(this.Type); if (!TypeLookup.CoreTypeLookup(enumEnderlyingType, out CoreType enumCoreTypeLookup)) { throw new NotImplementedException("Should not happen"); } this.EnumUnderlyingType = enumCoreTypeLookup; } else if (this.IsNullable && this.InnerTypes[0].IsEnum) { var enumEnderlyingType = Enum.GetUnderlyingType(this.InnerTypes[0]); if (!TypeLookup.CoreTypeLookup(enumEnderlyingType, out CoreType enumCoreTypeLookup)) { throw new NotImplementedException("Should not happen"); } enumCoreTypeLookup = enumCoreTypeLookup switch { Reflection.CoreType.Byte => Reflection.CoreType.ByteNullable, Reflection.CoreType.SByte => Reflection.CoreType.SByteNullable, Reflection.CoreType.Int16 => Reflection.CoreType.Int16Nullable, Reflection.CoreType.UInt16 => Reflection.CoreType.UInt16Nullable, Reflection.CoreType.Int32 => Reflection.CoreType.Int32Nullable, Reflection.CoreType.UInt32 => Reflection.CoreType.UInt32Nullable, Reflection.CoreType.Int64 => Reflection.CoreType.Int64Nullable, Reflection.CoreType.UInt64 => Reflection.CoreType.UInt64Nullable, _ => throw new NotImplementedException(), }; this.EnumUnderlyingType = enumCoreTypeLookup; } this.IsGraphLocalProperty = this.CoreType.HasValue || this.EnumUnderlyingType.HasValue || this.SpecialType.HasValue || this.Type.IsArray || (this.IsNullable && this.InnerTypes[0].IsArray); var methodDetails = new List <MethodDetail>(); if (!type.IsGenericTypeDefinition) { var methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); foreach (var method in methods) { methodDetails.Add(new MethodDetail(method)); } if (type.IsInterface) { foreach (var i in Interfaces) { var iMethods = i.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); foreach (var method in iMethods) { methodDetails.Add(new MethodDetail(method)); } } } } this.MethodDetails = methodDetails.ToArray(); var constructorDetails = new List <ConstructorDetails>(); if (!type.IsGenericTypeDefinition) { var constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (var constructor in constructors) { constructorDetails.Add(new ConstructorDetails(constructor)); } } this.ConstructorDetails = constructorDetails.ToArray(); if (!type.IsAbstract && !type.IsGenericTypeDefinition) { var emptyConstructor = this.ConstructorDetails.FirstOrDefault(x => x.ParametersInfo.Count == 0); if (emptyConstructor != null) { this.Creator = () => { return(emptyConstructor.Creator(null)); }; } else if (type.IsValueType && type.Name != "Void") { var constantExpression = Expression.Convert(Expression.Default(type), typeof(object)); var lambda = Expression.Lambda <Func <object> >(constantExpression).Compile(); this.Creator = lambda; } else if (type == typeof(string)) { this.Creator = () => { return(String.Empty); }; } } var test = type.Name; this.Attributes = type.GetCustomAttributes().ToArray(); if (!this.CoreType.HasValue) { var typeMembers = new List <MemberDetail>(); if (!type.IsGenericTypeDefinition) { var properties = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (type.IsInterface) { foreach (var i in Interfaces) { var iProperties = i.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var iFields = i.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); properties = properties.Concat(iProperties.Where(x => !properties.Select(y => y.Name).Contains(x.Name))).ToArray(); fields = fields.Concat(iFields.Where(x => !fields.Select(y => y.Name).Contains(x.Name))).ToArray(); } } foreach (var property in properties) { if (property.GetIndexParameters().Length > 0) { continue; } MemberDetail backingMember = null; var backingField = fields.FirstOrDefault(x => x.Name == $"<{property.Name}>k__BackingField"); if (backingField != null) { backingMember = new MemberDetail(backingField, null); } typeMembers.Add(new MemberDetail(property, backingMember)); } foreach (var field in fields.Where(x => !x.Name.EndsWith("k__BackingField"))) { typeMembers.Add(new MemberDetail(field, null)); } } this.MemberDetails = typeMembers.ToArray(); this.membersByName = this.MemberDetails.ToDictionary(x => x.Name); } else { var typeMembers = Array.Empty <MemberDetail>(); this.MemberDetails = typeMembers; this.membersByName = this.MemberDetails.ToDictionary(x => x.Name); } if (this.IsTask && this.Type.IsGenericType) { if (this.membersByName.TryGetValue("Result", out MemberDetail resultMember)) { this.TaskResultGetter = resultMember.Getter; } } }
public bool TryGetMember(string name, out MemberDetail member) { return(this.membersByName.TryGetValue(name, out member)); }