From ed714395093a8d359f1cb103daf0874c672d8e92 Mon Sep 17 00:00:00 2001 From: Zingabopp Date: Sat, 4 Jan 2020 12:12:30 -0600 Subject: [PATCH] Updated ReflectionUtil Added null checks for the GetField/Property/Method that throws an InvalidOperationException with an informative message. This does change the fail silently behavior it had before, but it would probably be better to know right away if it's failing. --- IPA.Loader/Utilities/ReflectionUtil.cs | 79 ++++++++++++++++++++------ 1 file changed, 62 insertions(+), 17 deletions(-) diff --git a/IPA.Loader/Utilities/ReflectionUtil.cs b/IPA.Loader/Utilities/ReflectionUtil.cs index 922be878..e5b0650e 100644 --- a/IPA.Loader/Utilities/ReflectionUtil.cs +++ b/IPA.Loader/Utilities/ReflectionUtil.cs @@ -15,12 +15,30 @@ namespace IPA.Utilities /// the object instance /// the field to set /// the value to set it to + /// thrown when is not a member of public static void SetPrivateField(this object obj, string fieldName, object value) { - var prop = obj.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); - prop?.SetValue(obj, value); + Type targetType = obj.GetType(); + obj.SetPrivateField(fieldName, value, targetType); } - + + /// + /// Sets a (potentially) private field on the target object. specifies the the field belongs to. + /// + /// the object instance + /// the field to set + /// the value to set it to + /// the object type the field belongs to + /// thrown when is not a member of + /// thrown when isn't assignable as + public static void SetPrivateField(this object obj, string fieldName, object value, Type targetType) + { + var prop = targetType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + if (prop == null) + throw new InvalidOperationException($"{fieldName} is not a member of {targetType.Name}"); + prop.SetValue(obj, value); + } + /// /// Gets the value of a (potentially) private field. /// @@ -28,24 +46,47 @@ namespace IPA.Utilities /// the object instance to pull from /// the name of the field to read /// the value of the field - public static T GetPrivateField(this object obj, string fieldName) - { - var prop = obj.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); - var value = prop?.GetValue(obj); - return (T) value; + /// thrown when is not a member of + public static T GetPrivateField(this object obj, string fieldName) + { + Type targetType = obj.GetType(); + return obj.GetPrivateField(fieldName, targetType); } - + + /// + /// Gets the value of a (potentially) private field. specifies the the field belongs to + /// + /// the type of the field (result casted) + /// the object instance to pull from + /// the name of the field to read + /// the object type the field belongs to + /// the value of the field + /// thrown when is not a member of + /// thrown when isn't assignable as + public static T GetPrivateField(this object obj, string fieldName, Type targetType) + { + var prop = targetType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (prop == null) + throw new InvalidOperationException($"{fieldName} is not a member of {targetType.Name}"); + var value = prop.GetValue(obj); + return (T)value; + } + /// /// Sets a (potentially) private property on the target object. /// /// the target object instance /// the name of the property /// the value to set it to - public static void SetPrivateProperty(this object obj, string propertyName, object value) - { - var prop = obj.GetType() - .GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); - prop?.SetValue(obj, value, null); + /// thrown when is not a member of + public static void SetPrivateProperty(this object obj, string propertyName, object value) + { + Type targetType = obj.GetType(); + var prop = targetType + .GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + if (prop == null) + throw new InvalidOperationException($"{propertyName} is not a member of {targetType.Name}"); + prop.SetValue(obj, value, null); } /// @@ -55,10 +96,14 @@ namespace IPA.Utilities /// the method name /// the method parameters /// the return value + /// thrown when is not a member of public static object InvokePrivateMethod(this object obj, string methodName, params object[] methodParams) - { - MethodInfo dynMethod = obj.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); - return dynMethod?.Invoke(obj, methodParams); + { + Type targetType = obj.GetType(); + MethodInfo dynMethod = targetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + if (dynMethod == null) + throw new InvalidOperationException($"{methodName} is not a member of {targetType.Name}"); + return dynMethod.Invoke(obj, methodParams); } ///