using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; namespace NaughtyAttributes.Editor { public static class ReflectionUtility { public static IEnumerable<FieldInfo> GetAllFields(object target, Func<FieldInfo, bool> predicate) { if (target == null) { Debug.LogError("The target object is null. Check for missing scripts."); yield break; } List<Type> types = GetSelfAndBaseTypes(target); for (int i = types.Count - 1; i >= 0; i--) { IEnumerable<FieldInfo> fieldInfos = types[i] .GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly) .Where(predicate); foreach (var fieldInfo in fieldInfos) { yield return fieldInfo; } } } public static IEnumerable<PropertyInfo> GetAllProperties(object target, Func<PropertyInfo, bool> predicate) { if (target == null) { Debug.LogError("The target object is null. Check for missing scripts."); yield break; } List<Type> types = GetSelfAndBaseTypes(target); for (int i = types.Count - 1; i >= 0; i--) { IEnumerable<PropertyInfo> propertyInfos = types[i] .GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly) .Where(predicate); foreach (var propertyInfo in propertyInfos) { yield return propertyInfo; } } } public static IEnumerable<MethodInfo> GetAllMethods(object target, Func<MethodInfo, bool> predicate) { if (target == null) { Debug.LogError("The target object is null. Check for missing scripts."); yield break; } List<Type> types = GetSelfAndBaseTypes(target); for (int i = types.Count - 1; i >= 0; i--) { IEnumerable<MethodInfo> methodInfos = types[i] .GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly) .Where(predicate); foreach (var methodInfo in methodInfos) { yield return methodInfo; } } } public static FieldInfo GetField(object target, string fieldName) { return GetAllFields(target, f => f.Name.Equals(fieldName, StringComparison.Ordinal)).FirstOrDefault(); } public static PropertyInfo GetProperty(object target, string propertyName) { return GetAllProperties(target, p => p.Name.Equals(propertyName, StringComparison.Ordinal)).FirstOrDefault(); } public static MethodInfo GetMethod(object target, string methodName) { return GetAllMethods(target, m => m.Name.Equals(methodName, StringComparison.Ordinal)).FirstOrDefault(); } public static Type GetListElementType(Type listType) { if (listType.IsGenericType) { return listType.GetGenericArguments()[0]; } else { return listType.GetElementType(); } } /// <summary> /// Get type and all base types of target, sorted as following: /// <para />[target's type, base type, base's base type, ...] /// </summary> /// <param name="target"></param> /// <returns></returns> private static List<Type> GetSelfAndBaseTypes(object target) { List<Type> types = new List<Type>() { target.GetType() }; while (types.Last().BaseType != null) { types.Add(types.Last().BaseType); } return types; } } }