利用反射,将两个对象之间属性名相同的value动态赋值
当一个对象里有很多字段,比如,学校,姓名,性别,年龄,电话号码,兴趣爱好..........
可能由于业务需求我只需要使用到姓名,电话号码,等少数的几个重要信息,而且在对象赋值的字段定义相同,
常常我们采用的方式是:
public class SourceModel { public int id { get; set; } public string name { get; set; } public int age { get; set; } public string sex { get; set; } } public class ReturnModel { public string name { get; set; } public int age { get; set; } } class TestThread { /// <summary> /// 常规模型转换 /// </summary> /// <param name="source"></param> /// <returns></returns> public static ReturnModel ModelConvert(SourceModel source) { if (source == null) { return null; } return new ReturnModel { name = source.name, age = source.age, //........... }; }
但是当未来需求变化了,我们要显示电话号码,年龄了,我们除了ReturnModel添加电话号码字段,还要在代码中添加赋值代码块(标红部分)
/// <summary> /// 常规模型转换 /// </summary> /// <param name="source"></param> /// <returns></returns> public static ReturnModel ModelConvert(SourceModel source) { if (source == null) { return null; } return new ReturnModel { name = source.name, age = source.age, phonenumber = source.phonenumber, }; }
但是如果涉及到类型转化的代码很多,或者说需要赋值转化的字段很多,那么这在赋值的时候,代码量也就显著增加了
为了减小工作量,我们可以采用:
/// <summary> /// 对象转换 /// 创建新对象,并将属性名相同的value赋予新对象 /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TReturn"></typeparam> /// <param name="source"></param> /// <returns></returns> public static TReturn ObjectToObject<TSource, TReturn>(TSource source) { var re = Activator.CreateInstance(typeof(TReturn)); var typeSource = typeof(TSource); foreach (var prop in re.GetType().GetProperties()) { var value = typeSource.GetProperty(prop.Name); if (value != null) { prop.SetValue(re, value.GetValue(source)); } } return (TReturn)re; }
执行结果如下:
当然反射效率要底点,就看如何取舍了。想得到些什么就不得不失去些什么...........滑稽