C#学习:表达式树
通过表达式树拼装lambda表达式,从而实现把一个类型的字段和属性的值复制到另外一个类型中去。
一、下面的方法实现两个类型间复制
/// <summary> /// 交换两个类型的属性(复制) /// </summary> /// <typeparam name="Tin"></typeparam> /// <typeparam name="Tout"></typeparam> public static class ExpressionCopy<Tin, Tout> { public static Tout Excharnge(Tin tin) { ParameterExpression experssionin = Expression.Parameter(typeof(Tin), "tModel");//创建实例 List<MemberBinding> memberList = new List<MemberBinding>();//绑定用的 foreach (var item in typeof(Tout).GetFields()) { FieldInfo field = typeof(Tin).GetField(item.Name.GetPropertyRemark(typeof(Tout), 1)); if (field != null) { MemberExpression member = Expression.Field(experssionin, field); MemberBinding binding = Expression.Bind(item, member); memberList.Add(binding); } } foreach (var item in typeof(Tout).GetProperties()) { PropertyInfo pro = typeof(Tin).GetProperty(item.Name.GetPropertyRemark(typeof(Tout), 2)); if (pro != null) { MemberExpression proper = Expression.Property(experssionin, pro); MemberBinding binding = Expression.Bind(item, proper); memberList.Add(binding); } } MemberInitExpression init = Expression.MemberInit(Expression.New(typeof(Tout)), memberList.ToArray());//初始化绑定新成员 Expression<Func<Tin, Tout>> lambda = Expression.Lambda<Func<Tin, Tout>>(init, new ParameterExpression[] { experssionin }); return lambda.Compile().Invoke(tin); } }
二、声明特性为了防止当要复制的属性字段名称不一致
/// <summary> /// 特性 /// </summary> public class GetRemarkAttribute : Attribute { public GetRemarkAttribute(string name) { this._remark = name; } private string _remark; public string GetRemark() { return _remark; } }
三、通过反射为string类型添加一个扩展方法,来获取特性的值
1 public static class GetRemark 2 { 3 /// <summary> 4 /// 通过反射获得特性 5 /// </summary> 6 /// <param name="values">字段属性名称</param> 7 /// <param name="type">类型</param> 8 /// <param name="parameter">参数1为字段2为属性</param> 9 /// <returns></returns> 10 public static string GetPropertyRemark(this string values, Type type, int parameter) 11 { 12 if (parameter == 1) 13 { 14 FieldInfo propperty = type.GetField(values); 15 16 if (propperty.IsDefined(typeof(GetRemarkAttribute))) 17 { 18 GetRemarkAttribute remark = (GetRemarkAttribute)propperty.GetCustomAttribute(typeof(GetRemarkAttribute)); 19 return remark.GetRemark(); 20 } 21 22 } 23 else 24 { 25 PropertyInfo propperty = type.GetProperty(values); 26 27 if (propperty.IsDefined(typeof(GetRemarkAttribute))) 28 { 29 GetRemarkAttribute remark = (GetRemarkAttribute)propperty.GetCustomAttribute(typeof(GetRemarkAttribute)); 30 return remark.GetRemark(); 31 } 32 33 } 34 return values; 35 36 } 37 }
四、下面就是实际操作调用
1 public class OldPersoninfo 2 { 3 public int Id { get; set; } 4 public string Name { get; set; } 5 public string Type { get; set; } 6 public OldPersoninfo() 7 { 8 Id = 2; 9 Name = "测试"; 10 Type = "非常类额"; 11 } 12 } 13 public class NewPersoninfo 14 { 15 public int Id { get; set; } 16 // [GetRemark("Name")] 17 public string newName { get; set; } 18 //[GetRemark("Type")] 19 public string newType { get; set; } 20 } 21 22 23 private void test_Load(object sender, EventArgs e) 24 { 25 OldPersoninfo old = new OldPersoninfo(); 26 NewPersoninfo newPersoninfo = ExpressionCopy<OldPersoninfo, NewPersoninfo>.Excharnge(old); 27 MessageBox.Show(newPersoninfo.newType); 28 }