Expression 获取,设置属性的值
有时候,业务需求,需要根据属性名称设置属性的值或者根据属性名称获取属性的值,原生的反射实现比较简单,我想用Expression Tree来实现,写成拓展方法,现在把它记录下来,下次直接用。
/// <summary> /// Object拓展方法,.Net4.0以上 /// </summary> public static class ObjectExtension { /// <summary> /// 根据属性名获取属性值 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="t">对象</param> /// <param name="name">属性名</param> /// <returns>属性的值</returns> public static object GetPropertyValue<T>(this T t, string name) { Type type = t.GetType(); PropertyInfo p = type.GetProperty(name); if (p == null) { throw new Exception(String.Format("该类型没有名为{0}的属性", name)); } var param_obj = Expression.Parameter(typeof(T)); var param_val = Expression.Parameter(typeof(object)); //转成真实类型,防止Dynamic类型转换成object var body_obj = Expression.Convert(param_obj, type); var body = Expression.Property(body_obj, p); var getValue = Expression.Lambda<Func<T, object>>(body, param_obj).Compile(); return getValue(t); } /// <summary> /// 根据属性名称设置属性的值 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="t">对象</param> /// <param name="name">属性名</param> /// <param name="value">属性的值</param> public static void SetPropertyValue<T>(this T t, string name, object value) { Type type = t.GetType(); PropertyInfo p = type.GetProperty(name); if (p == null) { throw new Exception(String.Format("该类型没有名为{0}的属性", name)); } var param_obj = Expression.Parameter(type); var param_val = Expression.Parameter(typeof(object)); var body_obj = Expression.Convert(param_obj, type); var body_val = Expression.Convert(param_val, p.PropertyType); //获取设置属性的值的方法 var setMethod = p.GetSetMethod(true); //如果只是只读,则setMethod==null if(setMethod!=null) { var body = Expression.Call(param_obj, p.GetSetMethod(), body_val); var setValue = Expression.Lambda<Action<T, object>>(body, param_obj, param_val).Compile(); setValue(t, value); } } } //测试例子 public class Person { public string Name { set; get; } } class Program { static void Main(string[] args) { var person = new Person() { Name = "123" }; dynamic p = new { Name = "123" }; object op = (object)p; Console.WriteLine("Person 的Name属性的值是{0}",person.GetPropertyValue("Name")); person.SetPropertyValue("Name", "456"); Console.WriteLine("Person 的Name属性的值修改后是{0}", person.Name); Console.WriteLine("dynamic 的Name属性的值是{0}", op.GetPropertyValue("Name")); op.SetPropertyValue("Name", 456); Console.WriteLine("dynamic 的Name属性的值修改后是{0}", op.GetPropertyValue("Name")); } }
测试结果
Person 的Name属性的值是123
Person 的Name属性的值修改后是456
dynamic 的Name属性的值是123
dynamic 的Name属性的值修改后是123
请按任意键继续. . .
出处:https://blog.csdn.net/sweety820/article/details/39203087
=======================================================================================
C#通过表达式获取属性名称,设置、获取属性值
转自 // https://blog.csdn.net/sweety820/article/details/39203087
参考 // https://stackoverflow.com/questions/32146571/expression-of-type-system-int64-cannot-be-used-for-return-type-system-object?noredirect=1&lq=1
代码如下:
/// <summary> /// Object拓展方法,.Net4.0以上 /// </summary> public static class ObjectExtension { /// <summary> /// 根据属性名获取属性值 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="t">对象</param> /// <param name="name">属性名</param> /// <returns>属性的值</returns> public static object GetPropertyValue<T>(this T t, string name) { Type type = t.GetType(); PropertyInfo p = type.GetProperty(name); if (p == null) { throw new Exception(String.Format("该类型没有名为{0}的属性", name)); } var param_obj = Expression.Parameter(typeof(T)); var param_val = Expression.Parameter(typeof(object)); // 原有的,非string类型会报转换object错误 转成真实类型,防止Dynamic类型转换成object //var body_obj = Expression.Convert(param_obj, type); //var body = Expression.Property(body_obj, p); //var getValue = Expression.Lambda<Func<T, object>>(body, param_obj).Compile(); //转成真实类型,防止Dynamic类型转换成object Expression<Func<T, object>> result = Expression.Lambda<Func<T, object>>(Expression.Convert(Expression.Property(param_obj, p), typeof(object)), param_obj); var getValue = result.Compile(); return getValue(t); } /// <summary> /// 根据属性名称设置属性的值 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="t">对象</param> /// <param name="name">属性名</param> /// <param name="value">属性的值</param> public static void SetPropertyValue<T>(this T t, string name, object value) { Type type = t.GetType(); PropertyInfo p = type.GetProperty(name); if (p == null) { throw new Exception(String.Format("该类型没有名为{0}的属性", name)); } var param_obj = Expression.Parameter(type); var param_val = Expression.Parameter(typeof(object)); var body_obj = Expression.Convert(param_obj, type); var body_val = Expression.Convert(param_val, p.PropertyType); //获取设置属性的值的方法 var setMethod = p.GetSetMethod(true); //如果只是只读,则setMethod==null if (setMethod != null) { var body = Expression.Call(param_obj, p.GetSetMethod(), body_val); var setValue = Expression.Lambda<Action<T, object>>(body, param_obj, param_val).Compile(); setValue(t, value); } } /// <summary> /// 获取类的属性名称 /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TProperty"></typeparam> /// <param name="source"></param> /// <param name="propery"></param> /// <returns></returns> public static string GetPropName<TSource, TProperty>(this TSource source, Expression<Func<TSource, TProperty>> propery) where TSource : class { var body = propery.Body.ToString(); return body.Substring(body.LastIndexOf(".") + 1); } public static PropertyInfo GetPropertyInfo<TSource, TProperty>( Expression<Func<TSource, TProperty>> propertyLambda) { Type type = typeof(TSource); MemberExpression member = propertyLambda.Body as MemberExpression; if (member == null) throw new ArgumentException(string.Format( "Expression '{0}' refers to a method, not a property.", propertyLambda.ToString())); PropertyInfo propInfo = member.Member as PropertyInfo; if (propInfo == null) throw new ArgumentException(string.Format( "Expression '{0}' refers to a field, not a property.", propertyLambda.ToString())); if (type != propInfo.ReflectedType && !type.IsSubclassOf(propInfo.ReflectedType)) throw new ArgumentException(string.Format( "Expresion '{0}' refers to a property that is not from type {1}.", propertyLambda.ToString(), type)); return propInfo; } /// <summary> /// 获取类的属性信息 /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TProperty"></typeparam> /// <param name="source"></param> /// <param name="propertyLambda"></param> /// <returns></returns> public static PropertyInfo GetPropertyInfo<TSource, TProperty>(this TSource source, Expression<Func<TSource, TProperty>> propertyLambda) where TSource : class { return GetPropertyInfo(propertyLambda); } /// <summary> /// 获取类的属性名称 /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TProperty"></typeparam> /// <param name="source"></param> /// <param name="propertyLambda"></param> /// <returns></returns> public static string NameOfProperty<TSource, TProperty>(this TSource source, Expression<Func<TSource, TProperty>> propertyLambda) where TSource : class { PropertyInfo prodInfo = GetPropertyInfo(propertyLambda); return prodInfo.Name; } }
出处:https://blog.csdn.net/XinShun/article/details/88978238
标签:body,obj,C#,param,var,Expression,属性 From: https://www.cnblogs.com/mq0036/p/16940895.html