當一個對象裏有很多字段,比如,學校,姓名,性別,年齡,電話號碼,興趣愛好..........
可能由於業務需求我只需要使用到姓名,電話號碼,等少數的幾個重要信息,而且在對象賦值的字段定義相同,
常常我們採用的方式是:
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; }
執行結果如下:
當然反射效率要底點,就看如何取捨了。想得到些什麼就不得不失去些什麼...........滑稽