using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; namespace NaughtyAttributes.Editor { public static class ReflectionUtility { public static IEnumerable GetAllFields(object target, Func predicate) { if (target == null) { Debug.LogError("The target object is null. Check for missing scripts."); yield break; } List types = GetSelfAndBaseTypes(target); for (int i = types.Count - 1; i >= 0; i--) { IEnumerable 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 GetAllProperties(object target, Func predicate) { if (target == null) { Debug.LogError("The target object is null. Check for missing scripts."); yield break; } List types = GetSelfAndBaseTypes(target); for (int i = types.Count - 1; i >= 0; i--) { IEnumerable 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 GetAllMethods(object target, Func predicate) { if (target == null) { Debug.LogError("The target object is null. Check for missing scripts."); yield break; } List types = GetSelfAndBaseTypes(target); for (int i = types.Count - 1; i >= 0; i--) { IEnumerable 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(); } } /// /// Get type and all base types of target, sorted as following: /// [target's type, base type, base's base type, ...] /// /// /// private static List GetSelfAndBaseTypes(object target) { List types = new List() { target.GetType() }; while (types.Last().BaseType != null) { types.Add(types.Last().BaseType); } return types; } } }