From 53df85f3123f8d9cb00013bb32b61c220ccad697 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 20 Oct 2017 16:37:22 -0400 Subject: enable access to public members using reflection API --- src/SMAPI/Framework/Reflection/Reflector.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/SMAPI/Framework/Reflection') diff --git a/src/SMAPI/Framework/Reflection/Reflector.cs b/src/SMAPI/Framework/Reflection/Reflector.cs index 5c2d90fa..23a48505 100644 --- a/src/SMAPI/Framework/Reflection/Reflector.cs +++ b/src/SMAPI/Framework/Reflection/Reflector.cs @@ -38,7 +38,7 @@ namespace StardewModdingAPI.Framework.Reflection throw new ArgumentNullException(nameof(obj), "Can't get a private instance field from a null object."); // get field from hierarchy - IPrivateField field = this.GetFieldFromHierarchy(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic); + IPrivateField field = this.GetFieldFromHierarchy(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (required && field == null) throw new InvalidOperationException($"The {obj.GetType().FullName} object doesn't have a private '{name}' instance field."); return field; @@ -52,7 +52,7 @@ namespace StardewModdingAPI.Framework.Reflection public IPrivateField GetPrivateField(Type type, string name, bool required = true) { // get field from hierarchy - IPrivateField field = this.GetFieldFromHierarchy(type, null, name, BindingFlags.NonPublic | BindingFlags.Static); + IPrivateField field = this.GetFieldFromHierarchy(type, null, name, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public); if (required && field == null) throw new InvalidOperationException($"The {type.FullName} object doesn't have a private '{name}' static field."); return field; @@ -73,7 +73,7 @@ namespace StardewModdingAPI.Framework.Reflection throw new ArgumentNullException(nameof(obj), "Can't get a private instance property from a null object."); // get property from hierarchy - IPrivateProperty property = this.GetPropertyFromHierarchy(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic); + IPrivateProperty property = this.GetPropertyFromHierarchy(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (required && property == null) throw new InvalidOperationException($"The {obj.GetType().FullName} object doesn't have a private '{name}' instance property."); return property; @@ -87,7 +87,7 @@ namespace StardewModdingAPI.Framework.Reflection public IPrivateProperty GetPrivateProperty(Type type, string name, bool required = true) { // get field from hierarchy - IPrivateProperty property = this.GetPropertyFromHierarchy(type, null, name, BindingFlags.NonPublic | BindingFlags.Static); + IPrivateProperty property = this.GetPropertyFromHierarchy(type, null, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); if (required && property == null) throw new InvalidOperationException($"The {type.FullName} object doesn't have a private '{name}' static property."); return property; @@ -107,7 +107,7 @@ namespace StardewModdingAPI.Framework.Reflection throw new ArgumentNullException(nameof(obj), "Can't get a private instance method from a null object."); // get method from hierarchy - IPrivateMethod method = this.GetMethodFromHierarchy(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic); + IPrivateMethod method = this.GetMethodFromHierarchy(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (required && method == null) throw new InvalidOperationException($"The {obj.GetType().FullName} object doesn't have a private '{name}' instance method."); return method; @@ -120,7 +120,7 @@ namespace StardewModdingAPI.Framework.Reflection public IPrivateMethod GetPrivateMethod(Type type, string name, bool required = true) { // get method from hierarchy - IPrivateMethod method = this.GetMethodFromHierarchy(type, null, name, BindingFlags.NonPublic | BindingFlags.Static); + IPrivateMethod method = this.GetMethodFromHierarchy(type, null, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); if (required && method == null) throw new InvalidOperationException($"The {type.FullName} object doesn't have a private '{name}' static method."); return method; @@ -141,7 +141,7 @@ namespace StardewModdingAPI.Framework.Reflection throw new ArgumentNullException(nameof(obj), "Can't get a private instance method from a null object."); // get method from hierarchy - PrivateMethod method = this.GetMethodFromHierarchy(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic, argumentTypes); + PrivateMethod method = this.GetMethodFromHierarchy(obj.GetType(), obj, name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, argumentTypes); if (required && method == null) throw new InvalidOperationException($"The {obj.GetType().FullName} object doesn't have a private '{name}' instance method with that signature."); return method; @@ -155,7 +155,7 @@ namespace StardewModdingAPI.Framework.Reflection public IPrivateMethod GetPrivateMethod(Type type, string name, Type[] argumentTypes, bool required = true) { // get field from hierarchy - PrivateMethod method = this.GetMethodFromHierarchy(type, null, name, BindingFlags.NonPublic | BindingFlags.Static, argumentTypes); + PrivateMethod method = this.GetMethodFromHierarchy(type, null, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, argumentTypes); if (required && method == null) throw new InvalidOperationException($"The {type.FullName} object doesn't have a private '{name}' static method with that signature."); return method; -- cgit From ded647aad41d8e3591a21bdd6aa6503273312a27 Mon Sep 17 00:00:00 2001 From: Entoarox Date: Fri, 13 Oct 2017 18:19:04 +0200 Subject: PrivateProperty.cs ~ Use delegates for performance --- src/SMAPI/Framework/Reflection/PrivateProperty.cs | 24 +++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'src/SMAPI/Framework/Reflection') diff --git a/src/SMAPI/Framework/Reflection/PrivateProperty.cs b/src/SMAPI/Framework/Reflection/PrivateProperty.cs index 08204b7e..8a75d925 100644 --- a/src/SMAPI/Framework/Reflection/PrivateProperty.cs +++ b/src/SMAPI/Framework/Reflection/PrivateProperty.cs @@ -19,6 +19,9 @@ namespace StardewModdingAPI.Framework.Reflection /// The display name shown in error messages. private string DisplayName => $"{this.ParentType.FullName}::{this.PropertyInfo.Name}"; + private readonly Func GetterDelegate; + private readonly Action SetterDelegate; + /********* ** Accessors @@ -39,20 +42,17 @@ namespace StardewModdingAPI.Framework.Reflection /// The is null for a non-static field, or not null for a static field. public PrivateProperty(Type parentType, object obj, PropertyInfo property, bool isStatic) { - // validate - if (parentType == null) - throw new ArgumentNullException(nameof(parentType)); - if (property == null) - throw new ArgumentNullException(nameof(property)); if (isStatic && obj != null) throw new ArgumentException("A static property cannot have an object instance."); if (!isStatic && obj == null) throw new ArgumentException("A non-static property must have an object instance."); - // save - this.ParentType = parentType; + this.ParentType = parentType ?? throw new ArgumentNullException(nameof(parentType)); this.Parent = obj; - this.PropertyInfo = property; + this.PropertyInfo = property ?? throw new ArgumentNullException(nameof(property)); + + this.GetterDelegate = (Func)Delegate.CreateDelegate(typeof(Func), this.PropertyInfo.GetMethod); + this.SetterDelegate = (Action)Delegate.CreateDelegate(typeof(Action), this.PropertyInfo.SetMethod); } /// Get the property value. @@ -60,7 +60,9 @@ namespace StardewModdingAPI.Framework.Reflection { try { - return (TValue)this.PropertyInfo.GetValue(this.Parent); + return this.GetterDelegate(this.Parent); + // Old version: Commented out in case of issues with new version + //return (TValue)this.PropertyInfo.GetValue(this.Parent); } catch (InvalidCastException) { @@ -78,7 +80,9 @@ namespace StardewModdingAPI.Framework.Reflection { try { - this.PropertyInfo.SetValue(this.Parent, value); + this.SetterDelegate(this.Parent, value); + // Old version: Commented out in case of issues with new version + //this.PropertyInfo.SetValue(this.Parent, value); } catch (InvalidCastException) { -- cgit From 191d65f8d9e90cc3a9788afcae852f8879962428 Mon Sep 17 00:00:00 2001 From: Entoarox Date: Fri, 13 Oct 2017 19:00:55 +0200 Subject: Fix: Instance type is required --- src/SMAPI/Framework/Reflection/PrivateProperty.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/SMAPI/Framework/Reflection') diff --git a/src/SMAPI/Framework/Reflection/PrivateProperty.cs b/src/SMAPI/Framework/Reflection/PrivateProperty.cs index 8a75d925..718594ee 100644 --- a/src/SMAPI/Framework/Reflection/PrivateProperty.cs +++ b/src/SMAPI/Framework/Reflection/PrivateProperty.cs @@ -51,8 +51,10 @@ namespace StardewModdingAPI.Framework.Reflection this.Parent = obj; this.PropertyInfo = property ?? throw new ArgumentNullException(nameof(property)); - this.GetterDelegate = (Func)Delegate.CreateDelegate(typeof(Func), this.PropertyInfo.GetMethod); - this.SetterDelegate = (Action)Delegate.CreateDelegate(typeof(Action), this.PropertyInfo.SetMethod); + Type[] types = new Type[] { this.PropertyInfo.DeclaringType, typeof(TValue)}; + + this.GetterDelegate = (Func)Delegate.CreateDelegate(typeof(Func<,>).MakeGenericType(types), this.PropertyInfo.GetMethod); + this.SetterDelegate = (Action)Delegate.CreateDelegate(typeof(Action<,>).MakeGenericType(types), this.PropertyInfo.SetMethod); } /// Get the property value. -- cgit From 7e02310a8ea9c24607a88718ee10ac5f85836fdb Mon Sep 17 00:00:00 2001 From: Entoarox Date: Mon, 23 Oct 2017 18:15:18 +0200 Subject: Fix object cast being needed - use closed instead of open delegate The API does not allow the user to modify the `this` after the fact anyhow, so it isnt needed. --- src/SMAPI/Framework/Reflection/PrivateProperty.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/SMAPI/Framework/Reflection') diff --git a/src/SMAPI/Framework/Reflection/PrivateProperty.cs b/src/SMAPI/Framework/Reflection/PrivateProperty.cs index 718594ee..0fa10601 100644 --- a/src/SMAPI/Framework/Reflection/PrivateProperty.cs +++ b/src/SMAPI/Framework/Reflection/PrivateProperty.cs @@ -19,8 +19,8 @@ namespace StardewModdingAPI.Framework.Reflection /// The display name shown in error messages. private string DisplayName => $"{this.ParentType.FullName}::{this.PropertyInfo.Name}"; - private readonly Func GetterDelegate; - private readonly Action SetterDelegate; + private readonly Func GetterDelegate; + private readonly Action SetterDelegate; /********* @@ -53,8 +53,8 @@ namespace StardewModdingAPI.Framework.Reflection Type[] types = new Type[] { this.PropertyInfo.DeclaringType, typeof(TValue)}; - this.GetterDelegate = (Func)Delegate.CreateDelegate(typeof(Func<,>).MakeGenericType(types), this.PropertyInfo.GetMethod); - this.SetterDelegate = (Action)Delegate.CreateDelegate(typeof(Action<,>).MakeGenericType(types), this.PropertyInfo.SetMethod); + this.GetterDelegate = (Func)Delegate.CreateDelegate(typeof(Func), obj, this.PropertyInfo.GetMethod); + this.SetterDelegate = (Action)Delegate.CreateDelegate(typeof(Action), obj, this.PropertyInfo.SetMethod); } /// Get the property value. @@ -62,7 +62,7 @@ namespace StardewModdingAPI.Framework.Reflection { try { - return this.GetterDelegate(this.Parent); + return this.GetterDelegate(); // Old version: Commented out in case of issues with new version //return (TValue)this.PropertyInfo.GetValue(this.Parent); } @@ -82,7 +82,7 @@ namespace StardewModdingAPI.Framework.Reflection { try { - this.SetterDelegate(this.Parent, value); + this.SetterDelegate(value); // Old version: Commented out in case of issues with new version //this.PropertyInfo.SetValue(this.Parent, value); } -- cgit From f6a86e584976c87f1f678a226f8eafe6a8b9860c Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 24 Oct 2017 20:28:18 -0400 Subject: minor cleanup --- src/SMAPI/Framework/Reflection/PrivateProperty.cs | 30 +++++++++++------------ 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'src/SMAPI/Framework/Reflection') diff --git a/src/SMAPI/Framework/Reflection/PrivateProperty.cs b/src/SMAPI/Framework/Reflection/PrivateProperty.cs index 0fa10601..be346d71 100644 --- a/src/SMAPI/Framework/Reflection/PrivateProperty.cs +++ b/src/SMAPI/Framework/Reflection/PrivateProperty.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Reflection; namespace StardewModdingAPI.Framework.Reflection @@ -10,16 +10,13 @@ namespace StardewModdingAPI.Framework.Reflection /********* ** Properties *********/ - /// The type that has the field. - private readonly Type ParentType; - - /// The object that has the instance field (if applicable). - private readonly object Parent; - /// The display name shown in error messages. - private string DisplayName => $"{this.ParentType.FullName}::{this.PropertyInfo.Name}"; + private readonly string DisplayName; + /// The underlying property getter. private readonly Func GetterDelegate; + + /// The underlying property setter. private readonly Action SetterDelegate; @@ -42,16 +39,21 @@ namespace StardewModdingAPI.Framework.Reflection /// The is null for a non-static field, or not null for a static field. public PrivateProperty(Type parentType, object obj, PropertyInfo property, bool isStatic) { + // validate input + if (parentType == null) + throw new ArgumentNullException(nameof(parentType)); + if (property == null) + throw new ArgumentNullException(nameof(property)); + + // validate static if (isStatic && obj != null) throw new ArgumentException("A static property cannot have an object instance."); if (!isStatic && obj == null) throw new ArgumentException("A non-static property must have an object instance."); - this.ParentType = parentType ?? throw new ArgumentNullException(nameof(parentType)); - this.Parent = obj; - this.PropertyInfo = property ?? throw new ArgumentNullException(nameof(property)); - Type[] types = new Type[] { this.PropertyInfo.DeclaringType, typeof(TValue)}; + this.DisplayName = $"{parentType.FullName}::{property.Name}"; + this.PropertyInfo = property; this.GetterDelegate = (Func)Delegate.CreateDelegate(typeof(Func), obj, this.PropertyInfo.GetMethod); this.SetterDelegate = (Action)Delegate.CreateDelegate(typeof(Action), obj, this.PropertyInfo.SetMethod); @@ -63,8 +65,6 @@ namespace StardewModdingAPI.Framework.Reflection try { return this.GetterDelegate(); - // Old version: Commented out in case of issues with new version - //return (TValue)this.PropertyInfo.GetValue(this.Parent); } catch (InvalidCastException) { @@ -83,8 +83,6 @@ namespace StardewModdingAPI.Framework.Reflection try { this.SetterDelegate(value); - // Old version: Commented out in case of issues with new version - //this.PropertyInfo.SetValue(this.Parent, value); } catch (InvalidCastException) { -- cgit