using System; using System.Linq; namespace WX.CRM.Common { public class Mapper { /// /// 通过反射,将 T1 映射为 T2 /// /// /// /// /// public static T2 T1MapToT2(T1 t1) where T1 : class where T2 : class //, new() { T2 t2 = Activator.CreateInstance(); //T2 t2 = new T2(); //后面这种写法,要在 where 中添加 new() if (t1 == null) { return t2; } var p1 = t1.GetType().GetProperties(); var p2 = typeof(T2).GetProperties(); for (int i = 0; i < p1.Length; i++) { //条件:1、属性名相同;2、t2属性可写;3、属性可读性一致;4、数据类型相近(相同,或者接近。接近如:int 和 int?) var p = p2.Where(t => t.Name == p1[i].Name && t.CanWrite && t.CanRead == p1[i].CanRead).FirstOrDefault(); if (p == null) continue; var v = p1[i].GetValue(t1); if (v == null) continue; try { p.SetValue(t2, v); } //难判定数据类型,暂时这样处理 catch { try { p.SetValue(t2, Convert.ChangeType(v, p.PropertyType)); } //int? -> object -> int? 会抛错 catch { } } } return t2; } //这种写法和上面的写法没啥差别 public static T2 T1MapToT2_2(T1 t1) where T1 : class where T2 : class //, new() { T2 t2 = Activator.CreateInstance(); //T2 t2 = new T2(); //后面这种写法,要在 where 中添加 new() var p1 = t1.GetType().GetProperties(); var p2 = typeof(T2); for (int i = 0; i < p1.Length; i++) { //条件:1、属性名相同;2、t2属性可写;3、属性可读性一致;4、数据类型相近(相同,或者接近。接近如:int 和 int?) var p = p2.GetProperty(p1[i].Name); if (p == null || !p.CanWrite || p.CanRead != p1[i].CanRead) continue; var v = p1[i].GetValue(t1); if (v == null) continue; try { p.SetValue(t2, Convert.ChangeType(v, p.PropertyType)); } catch { } } return t2; } } }