通过表达式树拼装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 }