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
This commit is contained in:
Kurt 2017-05-28 14:49:36 -07:00
parent 8eed9f84ba
commit 87e99bf183
3 changed files with 66 additions and 3 deletions

View file

@ -7,6 +7,7 @@ using System.IO;
using System.Linq;
using System.Windows.Forms;
using PKHeX.Core;
using System.Reflection;
namespace PKHeX.WinForms
{
@ -440,7 +441,7 @@ namespace PKHeX.WinForms
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 @@ namespace PKHeX.WinForms
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<string> 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<string> 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<string> 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);
}
}
}

View file

@ -512,7 +512,7 @@ namespace PKHeX.WinForms
{
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}."); }

View file

@ -288,7 +288,7 @@ namespace PKHeX.WinForms
{
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}."); }