<PackageReference Include="Newtonsoft.Json" Version="6.0.7" />

ReflectionUtils

static class ReflectionUtils
using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Numerics; using System.Reflection; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters; using System.Text; namespace Newtonsoft.Json.Utilities { internal static class ReflectionUtils { public static readonly Type[] EmptyTypes; static ReflectionUtils() { EmptyTypes = Type.EmptyTypes; } public static bool IsVirtual(this PropertyInfo propertyInfo) { ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); MethodInfo getMethod = propertyInfo.GetGetMethod(); if (getMethod != (MethodInfo)null && getMethod.IsVirtual) return true; getMethod = propertyInfo.GetSetMethod(); if (getMethod != (MethodInfo)null && getMethod.IsVirtual) return true; return false; } public static MethodInfo GetBaseDefinition(this PropertyInfo propertyInfo) { ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); MethodInfo getMethod = propertyInfo.GetGetMethod(); if (getMethod != (MethodInfo)null) return getMethod.GetBaseDefinition(); getMethod = propertyInfo.GetSetMethod(); if (getMethod != (MethodInfo)null) return getMethod.GetBaseDefinition(); return null; } public static bool IsPublic(PropertyInfo property) { if (property.GetGetMethod() != (MethodInfo)null && property.GetGetMethod().IsPublic) return true; if (property.GetSetMethod() != (MethodInfo)null && property.GetSetMethod().IsPublic) return true; return false; } public static Type GetObjectType(object v) { return v?.GetType(); } public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat, SerializationBinder binder) { string text; if (binder != null) { binder.BindToName(t, out string assemblyName, out string typeName); text = typeName + ((assemblyName == null) ? "" : (", " + assemblyName)); } else text = t.AssemblyQualifiedName; switch (assemblyFormat) { case FormatterAssemblyStyle.Simple: return RemoveAssemblyDetails(text); case FormatterAssemblyStyle.Full: return text; default: throw new ArgumentOutOfRangeException(); } } private static string RemoveAssemblyDetails(string fullyQualifiedTypeName) { StringBuilder stringBuilder = new StringBuilder(); bool flag = false; bool flag2 = false; foreach (char c in fullyQualifiedTypeName) { switch (c) { case '[': flag = false; flag2 = false; stringBuilder.Append(c); break; case ']': flag = false; flag2 = false; stringBuilder.Append(c); break; case ',': if (!flag) { flag = true; stringBuilder.Append(c); } else flag2 = true; break; default: if (!flag2) stringBuilder.Append(c); break; } } return stringBuilder.ToString(); } public static bool HasDefaultConstructor(Type t, bool nonPublic) { ValidationUtils.ArgumentNotNull(t, "t"); if (t.IsValueType()) return true; return GetDefaultConstructor(t, nonPublic) != (ConstructorInfo)null; } public static ConstructorInfo GetDefaultConstructor(Type t) { return GetDefaultConstructor(t, false); } public static ConstructorInfo GetDefaultConstructor(Type t, bool nonPublic) { BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public; if (nonPublic) bindingFlags |= BindingFlags.NonPublic; return t.GetConstructors(bindingFlags).SingleOrDefault((ConstructorInfo c) => !c.GetParameters().Any()); } public static bool IsNullable(Type t) { ValidationUtils.ArgumentNotNull(t, "t"); if (t.IsValueType()) return IsNullableType(t); return true; } public static bool IsNullableType(Type t) { ValidationUtils.ArgumentNotNull(t, "t"); if (t.IsGenericType()) return t.GetGenericTypeDefinition() == typeof(Nullable<>); return false; } public static Type EnsureNotNullableType(Type t) { if (!IsNullableType(t)) return t; return Nullable.GetUnderlyingType(t); } public static bool IsGenericDefinition(Type type, Type genericInterfaceDefinition) { if (!type.IsGenericType()) return false; Type genericTypeDefinition = type.GetGenericTypeDefinition(); return genericTypeDefinition == genericInterfaceDefinition; } public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition) { Type implementingType; return ImplementsGenericDefinition(type, genericInterfaceDefinition, out implementingType); } public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition, out Type implementingType) { ValidationUtils.ArgumentNotNull(type, "type"); ValidationUtils.ArgumentNotNull(genericInterfaceDefinition, "genericInterfaceDefinition"); if (!genericInterfaceDefinition.IsInterface() || !genericInterfaceDefinition.IsGenericTypeDefinition()) throw new ArgumentNullException("'{0}' is not a generic interface definition.".FormatWith(CultureInfo.InvariantCulture, genericInterfaceDefinition)); if (type.IsInterface() && type.IsGenericType()) { Type genericTypeDefinition = type.GetGenericTypeDefinition(); if (genericInterfaceDefinition == genericTypeDefinition) { implementingType = type; return true; } } Type[] interfaces = type.GetInterfaces(); foreach (Type type2 in interfaces) { if (type2.IsGenericType()) { Type genericTypeDefinition2 = type2.GetGenericTypeDefinition(); if (genericInterfaceDefinition == genericTypeDefinition2) { implementingType = type2; return true; } } } implementingType = null; return false; } public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition) { Type implementingType; return InheritsGenericDefinition(type, genericClassDefinition, out implementingType); } public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition, out Type implementingType) { ValidationUtils.ArgumentNotNull(type, "type"); ValidationUtils.ArgumentNotNull(genericClassDefinition, "genericClassDefinition"); if (!genericClassDefinition.IsClass() || !genericClassDefinition.IsGenericTypeDefinition()) throw new ArgumentNullException("'{0}' is not a generic class definition.".FormatWith(CultureInfo.InvariantCulture, genericClassDefinition)); return InheritsGenericDefinitionInternal(type, genericClassDefinition, out implementingType); } private static bool InheritsGenericDefinitionInternal(Type currentType, Type genericClassDefinition, out Type implementingType) { if (currentType.IsGenericType()) { Type genericTypeDefinition = currentType.GetGenericTypeDefinition(); if (genericClassDefinition == genericTypeDefinition) { implementingType = currentType; return true; } } if (currentType.BaseType() == (Type)null) { implementingType = null; return false; } return InheritsGenericDefinitionInternal(currentType.BaseType(), genericClassDefinition, out implementingType); } public static Type GetCollectionItemType(Type type) { ValidationUtils.ArgumentNotNull(type, "type"); if (type.IsArray) return type.GetElementType(); if (ImplementsGenericDefinition(type, typeof(IEnumerable<>), out Type implementingType)) { if (implementingType.IsGenericTypeDefinition()) throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type)); return implementingType.GetGenericArguments()[0]; } if (typeof(IEnumerable).IsAssignableFrom(type)) return null; throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type)); } public static void GetDictionaryKeyValueTypes(Type dictionaryType, out Type keyType, out Type valueType) { ValidationUtils.ArgumentNotNull(dictionaryType, "type"); if (ImplementsGenericDefinition(dictionaryType, typeof(IDictionary<, >), out Type implementingType)) { if (implementingType.IsGenericTypeDefinition()) throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType)); Type[] genericArguments = implementingType.GetGenericArguments(); keyType = genericArguments[0]; valueType = genericArguments[1]; } else { if (!typeof(IDictionary).IsAssignableFrom(dictionaryType)) throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType)); keyType = null; valueType = null; } } public static Type GetMemberUnderlyingType(MemberInfo member) { ValidationUtils.ArgumentNotNull(member, "member"); switch (member.MemberType()) { case MemberTypes.Field: return ((FieldInfo)member).FieldType; case MemberTypes.Property: return ((PropertyInfo)member).PropertyType; case MemberTypes.Event: return ((EventInfo)member).EventHandlerType; case MemberTypes.Method: return ((MethodInfo)member).ReturnType; default: throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo, EventInfo or MethodInfo", "member"); } } public static bool IsIndexedProperty(MemberInfo member) { ValidationUtils.ArgumentNotNull(member, "member"); PropertyInfo propertyInfo = member as PropertyInfo; if (propertyInfo != (PropertyInfo)null) return IsIndexedProperty(propertyInfo); return false; } public static bool IsIndexedProperty(PropertyInfo property) { ValidationUtils.ArgumentNotNull(property, "property"); return property.GetIndexParameters().Length > 0; } public static object GetMemberValue(MemberInfo member, object target) { ValidationUtils.ArgumentNotNull(member, "member"); ValidationUtils.ArgumentNotNull(target, "target"); switch (member.MemberType()) { case MemberTypes.Field: return ((FieldInfo)member).GetValue(target); case MemberTypes.Property: try { return ((PropertyInfo)member).GetValue(target, null); } catch (TargetParameterCountException innerException) { throw new ArgumentException("MemberInfo '{0}' has index parameters".FormatWith(CultureInfo.InvariantCulture, member.Name), innerException); } default: throw new ArgumentException("MemberInfo '{0}' is not of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, CultureInfo.InvariantCulture, member.Name), "member"); } } public static void SetMemberValue(MemberInfo member, object target, object value) { ValidationUtils.ArgumentNotNull(member, "member"); ValidationUtils.ArgumentNotNull(target, "target"); switch (member.MemberType()) { case MemberTypes.Field: ((FieldInfo)member).SetValue(target, value); break; case MemberTypes.Property: ((PropertyInfo)member).SetValue(target, value, null); break; default: throw new ArgumentException("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, member.Name), "member"); } } public static bool CanReadMemberValue(MemberInfo member, bool nonPublic) { switch (member.MemberType()) { case MemberTypes.Field: { FieldInfo fieldInfo = (FieldInfo)member; if (nonPublic) return true; if (fieldInfo.IsPublic) return true; return false; } case MemberTypes.Property: { PropertyInfo propertyInfo = (PropertyInfo)member; if (!propertyInfo.CanRead) return false; if (nonPublic) return true; return propertyInfo.GetGetMethod(nonPublic) != (MethodInfo)null; } default: return false; } } public static bool CanSetMemberValue(MemberInfo member, bool nonPublic, bool canSetReadOnly) { switch (member.MemberType()) { case MemberTypes.Field: { FieldInfo fieldInfo = (FieldInfo)member; if (fieldInfo.IsInitOnly && !canSetReadOnly) return false; if (nonPublic) return true; if (fieldInfo.IsPublic) return true; return false; } case MemberTypes.Property: { PropertyInfo propertyInfo = (PropertyInfo)member; if (!propertyInfo.CanWrite) return false; if (nonPublic) return true; return propertyInfo.GetSetMethod(nonPublic) != (MethodInfo)null; } default: return false; } } public static List<MemberInfo> GetFieldsAndProperties(Type type, BindingFlags bindingAttr) { List<MemberInfo> list = new List<MemberInfo>(); list.AddRange(GetFields(type, bindingAttr)); list.AddRange(GetProperties(type, bindingAttr)); List<MemberInfo> list2 = new List<MemberInfo>(list.Count); foreach (IGrouping<string, MemberInfo> item in from m in list group m by m.Name) { int num = item.Count(); IList<MemberInfo> list3 = item.ToList(); if (num == 1) list2.Add(list3.First()); else { IList<MemberInfo> list4 = new List<MemberInfo>(); foreach (MemberInfo item2 in list3) { if (list4.Count == 0) list4.Add(item2); else if (!IsOverridenGenericMember(item2, bindingAttr) || item2.Name == "Item") { list4.Add(item2); } } list2.AddRange(list4); } } return list2; } private static bool IsOverridenGenericMember(MemberInfo memberInfo, BindingFlags bindingAttr) { if (memberInfo.MemberType() != MemberTypes.Property) return false; PropertyInfo propertyInfo = (PropertyInfo)memberInfo; if (!propertyInfo.IsVirtual()) return false; Type declaringType = propertyInfo.DeclaringType; if (!declaringType.IsGenericType()) return false; Type genericTypeDefinition = declaringType.GetGenericTypeDefinition(); if (genericTypeDefinition == (Type)null) return false; MemberInfo[] member = genericTypeDefinition.GetMember(propertyInfo.Name, bindingAttr); if (member.Length == 0) return false; Type memberUnderlyingType = GetMemberUnderlyingType(member[0]); if (!memberUnderlyingType.IsGenericParameter) return false; return true; } public static T GetAttribute<T>(object attributeProvider) where T : Attribute { return GetAttribute<T>(attributeProvider, true); } public static T GetAttribute<T>(object attributeProvider, bool inherit) where T : Attribute { T[] attributes = GetAttributes<T>(attributeProvider, inherit); if (attributes == null) return null; return attributes.SingleOrDefault(); } public static T[] GetAttributes<T>(object attributeProvider, bool inherit) where T : Attribute { return (T[])GetAttributes(attributeProvider, typeof(T), inherit); } public static Attribute[] GetAttributes(object attributeProvider, Type attributeType, bool inherit) { ValidationUtils.ArgumentNotNull(attributeProvider, "attributeProvider"); if (attributeProvider is Type) return (Attribute[])((Type)attributeProvider).GetCustomAttributes(attributeType, inherit); if (attributeProvider is Assembly) return Attribute.GetCustomAttributes((Assembly)attributeProvider, attributeType); if (attributeProvider is MemberInfo) return Attribute.GetCustomAttributes((MemberInfo)attributeProvider, attributeType, inherit); if (attributeProvider is Module) return Attribute.GetCustomAttributes((Module)attributeProvider, attributeType, inherit); if (attributeProvider is ParameterInfo) return Attribute.GetCustomAttributes((ParameterInfo)attributeProvider, attributeType, inherit); return (Attribute[])((ICustomAttributeProvider)attributeProvider).GetCustomAttributes(attributeType, inherit); } public static void SplitFullyQualifiedTypeName(string fullyQualifiedTypeName, out string typeName, out string assemblyName) { int? assemblyDelimiterIndex = GetAssemblyDelimiterIndex(fullyQualifiedTypeName); if (assemblyDelimiterIndex.HasValue) { typeName = fullyQualifiedTypeName.Substring(0, assemblyDelimiterIndex.Value).Trim(); assemblyName = fullyQualifiedTypeName.Substring(assemblyDelimiterIndex.Value + 1, fullyQualifiedTypeName.Length - assemblyDelimiterIndex.Value - 1).Trim(); } else { typeName = fullyQualifiedTypeName; assemblyName = null; } } private static int? GetAssemblyDelimiterIndex(string fullyQualifiedTypeName) { int num = 0; for (int i = 0; i < fullyQualifiedTypeName.Length; i++) { switch (fullyQualifiedTypeName[i]) { case '[': num++; break; case ']': num--; break; case ',': if (num == 0) return i; break; } } return null; } public static MemberInfo GetMemberInfoFromType(Type targetType, MemberInfo memberInfo) { MemberTypes memberTypes = memberInfo.MemberType(); if (memberTypes == MemberTypes.Property) { PropertyInfo propertyInfo = (PropertyInfo)memberInfo; Type[] types = (from p in propertyInfo.GetIndexParameters() select p.ParameterType).ToArray(); return targetType.GetProperty(propertyInfo.Name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, propertyInfo.PropertyType, types, null); } return targetType.GetMember(memberInfo.Name, memberInfo.MemberType(), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).SingleOrDefault(); } public static IEnumerable<FieldInfo> GetFields(Type targetType, BindingFlags bindingAttr) { ValidationUtils.ArgumentNotNull(targetType, "targetType"); List<MemberInfo> list = new List<MemberInfo>(targetType.GetFields(bindingAttr)); GetChildPrivateFields(list, targetType, bindingAttr); return list.Cast<FieldInfo>(); } private static void GetChildPrivateFields(IList<MemberInfo> initialFields, Type targetType, BindingFlags bindingAttr) { if ((bindingAttr & BindingFlags.NonPublic) != 0) { BindingFlags bindingAttr2 = bindingAttr.RemoveFlag(BindingFlags.Public); while ((targetType = targetType.BaseType()) != (Type)null) { IEnumerable<MemberInfo> collection = (from f in targetType.GetFields(bindingAttr2) where f.IsPrivate select f).Cast<MemberInfo>(); initialFields.AddRange(collection); } } } public static IEnumerable<PropertyInfo> GetProperties(Type targetType, BindingFlags bindingAttr) { ValidationUtils.ArgumentNotNull(targetType, "targetType"); List<PropertyInfo> list = new List<PropertyInfo>(targetType.GetProperties(bindingAttr)); GetChildPrivateProperties(list, targetType, bindingAttr); for (int i = 0; i < list.Count; i++) { PropertyInfo propertyInfo = list[i]; if (propertyInfo.DeclaringType != targetType) { PropertyInfo propertyInfo3 = list[i] = (PropertyInfo)GetMemberInfoFromType(propertyInfo.DeclaringType, propertyInfo); } } return list; } public static BindingFlags RemoveFlag(this BindingFlags bindingAttr, BindingFlags flag) { if ((bindingAttr & flag) != flag) return bindingAttr; return bindingAttr ^ flag; } private static void GetChildPrivateProperties(IList<PropertyInfo> initialProperties, Type targetType, BindingFlags bindingAttr) { while ((targetType = targetType.BaseType()) != (Type)null) { PropertyInfo[] properties = targetType.GetProperties(bindingAttr); foreach (PropertyInfo propertyInfo in properties) { PropertyInfo subTypeProperty = propertyInfo; if (!IsPublic(subTypeProperty)) { int num = initialProperties.IndexOf((PropertyInfo p) => p.Name == subTypeProperty.Name); if (num == -1) initialProperties.Add(subTypeProperty); else { PropertyInfo property = initialProperties[num]; if (!IsPublic(property)) initialProperties[num] = subTypeProperty; } } else if (!subTypeProperty.IsVirtual()) { int num2 = initialProperties.IndexOf(delegate(PropertyInfo p) { if (p.Name == subTypeProperty.Name) return p.DeclaringType == subTypeProperty.DeclaringType; return false; }); if (num2 == -1) initialProperties.Add(subTypeProperty); } else { int num3 = initialProperties.IndexOf(delegate(PropertyInfo p) { if (p.Name == subTypeProperty.Name && p.IsVirtual() && p.GetBaseDefinition() != (MethodInfo)null) return p.GetBaseDefinition().DeclaringType.IsAssignableFrom(subTypeProperty.DeclaringType); return false; }); if (num3 == -1) initialProperties.Add(subTypeProperty); } } } } public static bool IsMethodOverridden(Type currentType, Type methodDeclaringType, string method) { return currentType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any(delegate(MethodInfo info) { if (info.Name == method && info.DeclaringType != methodDeclaringType) return info.GetBaseDefinition().DeclaringType == methodDeclaringType; return false; }); } public static object GetDefaultValue(Type type) { if (type.IsValueType()) { switch (ConvertUtils.GetTypeCode(type)) { case PrimitiveTypeCode.Boolean: return false; case PrimitiveTypeCode.Char: case PrimitiveTypeCode.SByte: case PrimitiveTypeCode.Int16: case PrimitiveTypeCode.UInt16: case PrimitiveTypeCode.Int32: case PrimitiveTypeCode.Byte: case PrimitiveTypeCode.UInt32: return 0; case PrimitiveTypeCode.Int64: case PrimitiveTypeCode.UInt64: return 0; case PrimitiveTypeCode.Single: return 0; case PrimitiveTypeCode.Double: return 0; case PrimitiveTypeCode.Decimal: return 0; case PrimitiveTypeCode.DateTime: return default(DateTime); case PrimitiveTypeCode.BigInteger: return default(BigInteger); case PrimitiveTypeCode.Guid: return default(Guid); case PrimitiveTypeCode.DateTimeOffset: return default(DateTimeOffset); default: if (IsNullable(type)) return null; return Activator.CreateInstance(type); } } return null; } } }