diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2016-12-27 13:52:32 -0500 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2016-12-27 13:52:32 -0500 |
commit | b9dd6eb742e4f0c42ed887abd0f17f113f250056 (patch) | |
tree | 352a208a25780285419b0bae73148a00a98356ff /src/StardewModdingAPI/Framework/Reflection | |
parent | c24294c3dd73db3754d10ff8fe5bd51338555638 (diff) | |
parent | b75d86e7cc19f9bc961abb475f22e8f2b059533c (diff) | |
download | SMAPI-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.cs | 30 | ||||
-rw-r--r-- | src/StardewModdingAPI/Framework/Reflection/ReflectionHelper.cs | 34 |
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 +} |