summaryrefslogtreecommitdiff
path: root/src/StardewModdingAPI/Framework/Reflection
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2016-12-27 13:52:32 -0500
committerJesse Plamondon-Willard <github@jplamondonw.com>2016-12-27 13:52:32 -0500
commitb9dd6eb742e4f0c42ed887abd0f17f113f250056 (patch)
tree352a208a25780285419b0bae73148a00a98356ff /src/StardewModdingAPI/Framework/Reflection
parentc24294c3dd73db3754d10ff8fe5bd51338555638 (diff)
parentb75d86e7cc19f9bc961abb475f22e8f2b059533c (diff)
downloadSMAPI-b9dd6eb742e4f0c42ed887abd0f17f113f250056.tar.gz
SMAPI-b9dd6eb742e4f0c42ed887abd0f17f113f250056.tar.bz2
SMAPI-b9dd6eb742e4f0c42ed887abd0f17f113f250056.zip
Merge branch 'develop' into stable
Diffstat (limited to 'src/StardewModdingAPI/Framework/Reflection')
-rw-r--r--src/StardewModdingAPI/Framework/Reflection/CacheEntry.cs30
-rw-r--r--src/StardewModdingAPI/Framework/Reflection/ReflectionHelper.cs34
2 files changed, 57 insertions, 7 deletions
diff --git a/src/StardewModdingAPI/Framework/Reflection/CacheEntry.cs b/src/StardewModdingAPI/Framework/Reflection/CacheEntry.cs
new file mode 100644
index 00000000..30faca37
--- /dev/null
+++ b/src/StardewModdingAPI/Framework/Reflection/CacheEntry.cs
@@ -0,0 +1,30 @@
+using System.Reflection;
+
+namespace StardewModdingAPI.Framework.Reflection
+{
+ /// <summary>A cached member reflection result.</summary>
+ internal struct CacheEntry
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>Whether the lookup found a valid match.</summary>
+ public bool IsValid;
+
+ /// <summary>The reflection data for this member (or <c>null</c> if invalid).</summary>
+ public MemberInfo MemberInfo;
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance.</summary>
+ /// <param name="isValid">Whether the lookup found a valid match.</param>
+ /// <param name="memberInfo">The reflection data for this member (or <c>null</c> if invalid).</param>
+ public CacheEntry(bool isValid, MemberInfo memberInfo)
+ {
+ this.IsValid = isValid;
+ this.MemberInfo = memberInfo;
+ }
+ }
+}
diff --git a/src/StardewModdingAPI/Framework/Reflection/ReflectionHelper.cs b/src/StardewModdingAPI/Framework/Reflection/ReflectionHelper.cs
index 38b4e357..edf59b81 100644
--- a/src/StardewModdingAPI/Framework/Reflection/ReflectionHelper.cs
+++ b/src/StardewModdingAPI/Framework/Reflection/ReflectionHelper.cs
@@ -67,10 +67,17 @@ namespace StardewModdingAPI.Framework.Reflection
/// <param name="obj">The object which has the field.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
- /// <remarks>This is a shortcut for <see cref="GetPrivateField{TValue}(object,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.</remarks>
+ /// <returns>Returns the field value, or the default value for <typeparamref name="TValue"/> if the field wasn't found and <paramref name="required"/> is false.</returns>
+ /// <remarks>
+ /// This is a shortcut for <see cref="GetPrivateField{TValue}(object,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.
+ /// When <paramref name="required" /> is false, this will return the default value if reflection fails. If you need to check whether the field exists, use <see cref="GetPrivateField{TValue}(object,string,bool)" /> instead.
+ /// </remarks>
public TValue GetPrivateValue<TValue>(object obj, string name, bool required = true)
{
- return this.GetPrivateField<TValue>(obj, name, required).GetValue();
+ IPrivateField<TValue> field = this.GetPrivateField<TValue>(obj, name, required);
+ return field != null
+ ? field.GetValue()
+ : default(TValue);
}
/// <summary>Get the value of a private static field.</summary>
@@ -78,10 +85,17 @@ namespace StardewModdingAPI.Framework.Reflection
/// <param name="type">The type which has the field.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
- /// <remarks>This is a shortcut for <see cref="GetPrivateField{TValue}(Type,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.</remarks>
+ /// <returns>Returns the field value, or the default value for <typeparamref name="TValue"/> if the field wasn't found and <paramref name="required"/> is false.</returns>
+ /// <remarks>
+ /// This is a shortcut for <see cref="GetPrivateField{TValue}(Type,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.
+ /// When <paramref name="required" /> is false, this will return the default value if reflection fails. If you need to check whether the field exists, use <see cref="GetPrivateField{TValue}(Type,string,bool)" /> instead.
+ /// </remarks>
public TValue GetPrivateValue<TValue>(Type type, string name, bool required = true)
{
- return this.GetPrivateField<TValue>(type, name, required).GetValue();
+ IPrivateField<TValue> field = this.GetPrivateField<TValue>(type, name, required);
+ return field != null
+ ? field.GetValue()
+ : default(TValue);
}
/****
@@ -228,12 +242,18 @@ namespace StardewModdingAPI.Framework.Reflection
{
// get from cache
if (this.Cache.Contains(key))
- return (TMemberInfo)this.Cache[key];
+ {
+ CacheEntry entry = (CacheEntry)this.Cache[key];
+ return entry.IsValid
+ ? (TMemberInfo)entry.MemberInfo
+ : default(TMemberInfo);
+ }
// fetch & cache new value
TMemberInfo result = fetch();
- this.Cache.Add(key, result, new CacheItemPolicy { SlidingExpiration = this.SlidingCacheExpiry });
+ CacheEntry cacheEntry = new CacheEntry(result != null, result);
+ this.Cache.Add(key, cacheEntry, new CacheItemPolicy { SlidingExpiration = this.SlidingCacheExpiry });
return result;
}
}
-} \ No newline at end of file
+}