我试图在我的代码中使用Reflection1示例实现数据转换。
GetSourceValue函数有一个比较各种类型的开关,但我想删除这些类型和属性,并让GetSourceValue只使用一个字符串作为参数来获取属性的值。我想在字符串中传递一个类和属性,并解析属性的值。
这可能吗?
1原始博客文章的Web存档版本
我试图在我的代码中使用Reflection1示例实现数据转换。
GetSourceValue函数有一个比较各种类型的开关,但我想删除这些类型和属性,并让GetSourceValue只使用一个字符串作为参数来获取属性的值。我想在字符串中传递一个类和属性,并解析属性的值。
这可能吗?
1原始博客文章的Web存档版本
当前回答
关于嵌套属性的讨论,如果使用DataBinder,就可以避免所有反射的问题。Eval方法(对象,字符串)如下:
var value = DataBinder.Eval(DateTime.Now, "TimeOfDay.Hours");
当然,您需要添加对系统的引用。Web汇编,但这可能不是一个大问题。
其他回答
使用系统的PropertyInfo。反射的名称空间。无论我们试图访问什么属性,反射编译都很好。该错误将在运行时出现。
public static object GetObjProperty(object obj, string property)
{
Type t = obj.GetType();
PropertyInfo p = t.GetProperty("Location");
Point location = (Point)p.GetValue(obj, null);
return location;
}
它可以很好地获取对象的Location属性
Label1.Text = GetObjProperty(button1, "Location").ToString();
我们将得到Location: {X=71,Y=27} 我们还可以返回位置。X或位置。Y也一样。
这样怎么样:
public static Object GetPropValue(this Object obj, String name) {
foreach (String part in name.Split('.')) {
if (obj == null) { return null; }
Type type = obj.GetType();
PropertyInfo info = type.GetProperty(part);
if (info == null) { return null; }
obj = info.GetValue(obj, null);
}
return obj;
}
public static T GetPropValue<T>(this Object obj, String name) {
Object retval = GetPropValue(obj, name);
if (retval == null) { return default(T); }
// throws InvalidCastException if types are incompatible
return (T) retval;
}
这将允许你使用单个字符串进入属性,就像这样:
DateTime now = DateTime.Now;
int min = GetPropValue<int>(now, "TimeOfDay.Minutes");
int hrs = now.GetPropValue<int>("TimeOfDay.Hours");
您可以将这些方法用作静态方法或扩展。
看看Heleonix。反映图书馆。你可以通过路径获取/设置/调用成员,或者创建一个getter/setter (lambda编译成委托),这比反射更快。例如:
var success = Reflector.Get(DateTime.Now, null, "Date.Year", out int value);
或者只创建一个getter并缓存以供重用(这样性能更好,但如果中间成员为空可能会抛出NullReferenceException):
var getter = Reflector.CreateGetter<DateTime, int>("Date.Year", typeof(DateTime));
getter(DateTime.Now);
或者如果你想创建一个List<Action<object, object>>的不同getter,只需要为已编译的委托指定基本类型(类型转换将被添加到已编译的lambdas中):
var getter = Reflector.CreateGetter<object, object>("Date.Year", typeof(DateTime));
getter(DateTime.Now);
public static TValue GetFieldValue<TValue>(this object instance, string name)
{
var type = instance.GetType();
var field = type.GetFields(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).FirstOrDefault(e => typeof(TValue).IsAssignableFrom(e.FieldType) && e.Name == name);
return (TValue)field?.GetValue(instance);
}
public static TValue GetPropertyValue<TValue>(this object instance, string name)
{
var type = instance.GetType();
var field = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).FirstOrDefault(e => typeof(TValue).IsAssignableFrom(e.PropertyType) && e.Name == name);
return (TValue)field?.GetValue(instance);
}
捷径....
var a = new Test { Id = 1 , Name = "A" , date = DateTime.Now};
var b = new Test { Id = 1 , Name = "AXXX", date = DateTime.Now };
var compare = string.Join("",a.GetType().GetProperties().Select(x => x.GetValue(a)).ToArray())==
string.Join("",b.GetType().GetProperties().Select(x => x.GetValue(b)).ToArray());