From 87e99bf18349505b9e5872fae325f0dc5c562dce Mon Sep 17 00:00:00 2001 From: Kurt Date: Sun, 28 May 2017 14:49:36 -0700 Subject: [PATCH] Split reflection usage for winforms project batch editor needs more powerful variant which can check the base properties as well; just use the older code from before the .NET standard commit. Closes #1158 --- .../Subforms/PKM Editors/BatchEditor.cs | 65 ++++++++++++++++++- PKHeX.WinForms/Subforms/SAV_Database.cs | 2 +- PKHeX.WinForms/Subforms/SAV_MysteryGiftDB.cs | 2 +- 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/PKHeX.WinForms/Subforms/PKM Editors/BatchEditor.cs b/PKHeX.WinForms/Subforms/PKM Editors/BatchEditor.cs index a806ac63a..25b486675 100644 --- a/PKHeX.WinForms/Subforms/PKM Editors/BatchEditor.cs +++ b/PKHeX.WinForms/Subforms/PKM Editors/BatchEditor.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Windows.Forms; using PKHeX.Core; +using System.Reflection; namespace PKHeX.WinForms { @@ -440,7 +441,7 @@ private static ModifyResult tryModifyPKM(PKM PKM, IEnumerable continue; return ModifyResult.Filtered; } - if (!pkm.HasPropertyAll(typeof(PKM), cmd.PropertyName)) + if (!pkm.HasPropertyAll(cmd.PropertyName)) return ModifyResult.Filtered; if (ReflectUtil.GetValueEquals(PKM, cmd.PropertyName, cmd.PropertyValue) != cmd.Evaluator) return ModifyResult.Filtered; @@ -553,4 +554,66 @@ private static void setRandomIVs(PKM PKM, StringInstruction cmd) ReflectUtil.SetValue(PKM, cmd.PropertyName, Util.rnd32() & MaxIV); } } + + // Overrides PKHeX.Core's copy of ReflectUtil.cs; .NET standard does not support the same fetch for base classes. + public static class ReflectUtil + { + public static bool GetValueEquals(object obj, string propertyName, object value) + { + PropertyInfo pi = obj.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + var v = pi.GetValue(obj, null); + var c = ConvertValue(value, pi.PropertyType); + return v.Equals(c); + } + public static void SetValue(object obj, string propertyName, object value) + { + PropertyInfo pi = obj.GetType().GetProperty(propertyName); + pi.SetValue(obj, ConvertValue(value, pi.PropertyType), null); + } + + public static object GetValue(object obj, string propertyName) + { + PropertyInfo pi = obj.GetType().GetProperty(propertyName); + return pi.GetValue(obj, null); + } + + public static IEnumerable getPropertiesStartWithPrefix(Type type, string prefix, BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public) + { + return type.GetProperties(flags) + .Where(p => p.Name.StartsWith(prefix, StringComparison.Ordinal)) + .Select(p => p.Name); + } + public static IEnumerable getPropertiesCanWritePublic(Type type, BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public) + { + return type.GetProperties(flags) + .Where(p => p.CanWrite && p.GetSetMethod(nonPublic: true).IsPublic) + .Select(p => p.Name); + } + public static IEnumerable getPropertiesCanWritePublicDeclared(Type type) + { + return getPropertiesCanWritePublic(type, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); + } + public static bool HasProperty(this Type type, string name) + { + return type.GetProperty(name, BindingFlags.Public | BindingFlags.Instance) != null; + } + public static bool HasPropertyAll(this Type type, string name) + { + return type.GetProperty(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance) != null; + } + + private static object ConvertValue(object value, Type type) + { + if (type == typeof(DateTime?)) // Used for PKM.MetDate and other similar properties + { + DateTime dateValue; + return DateTime.TryParseExact(value.ToString(), "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateValue) + ? new DateTime?(dateValue) + : null; + } + + // Convert.ChangeType is suitable for most things + return Convert.ChangeType(value, type); + } + } } diff --git a/PKHeX.WinForms/Subforms/SAV_Database.cs b/PKHeX.WinForms/Subforms/SAV_Database.cs index 2dff7e292..c986d3153 100644 --- a/PKHeX.WinForms/Subforms/SAV_Database.cs +++ b/PKHeX.WinForms/Subforms/SAV_Database.cs @@ -512,7 +512,7 @@ private void B_Search_Click(object sender, EventArgs e) { if (cmd.PropertyName == nameof(PKM.Identifier) + "Contains") return pkm.Identifier.Contains(cmd.PropertyValue); - if (!pkm.GetType().HasPropertyAll(typeof(PKM), cmd.PropertyName)) + if (!pkm.GetType().HasPropertyAll(cmd.PropertyName)) return false; try { if (ReflectUtil.GetValueEquals(pkm, cmd.PropertyName, cmd.PropertyValue) == cmd.Evaluator) continue; } catch { Console.WriteLine($"Unable to compare {cmd.PropertyName} to {cmd.PropertyValue}."); } diff --git a/PKHeX.WinForms/Subforms/SAV_MysteryGiftDB.cs b/PKHeX.WinForms/Subforms/SAV_MysteryGiftDB.cs index bda91d91e..6b96ede5d 100644 --- a/PKHeX.WinForms/Subforms/SAV_MysteryGiftDB.cs +++ b/PKHeX.WinForms/Subforms/SAV_MysteryGiftDB.cs @@ -288,7 +288,7 @@ private void B_Search_Click(object sender, EventArgs e) { foreach (var cmd in filters) { - if (!gift.GetType().HasPropertyAll(typeof(PKM), cmd.PropertyName)) + if (!gift.GetType().HasPropertyAll(cmd.PropertyName)) return false; try { if (ReflectUtil.GetValueEquals(gift, cmd.PropertyName, cmd.PropertyValue) == cmd.Evaluator) continue; } catch { Console.WriteLine($"Unable to compare {cmd.PropertyName} to {cmd.PropertyValue}."); }