這兩天看一個要離職同事交接的代碼,看到一個淺拷貝的方法感覺挺好,在這裡記錄一下。
一、方法體
是一個靜態方法CopyHelper,包含以下三個部分
1、給PropertyInfo[]類型加個擴展的方法,方便進行查詢是否存在相同類型,相同名稱的字段。
/// <summary> /// PropertyInfo[]擴展方法,通過名稱獲得屬性 /// </summary> /// <param name="P"></param> /// <param name="pro"></param> /// <returns></returns> private static PropertyInfo GetPropertyByName(this PropertyInfo[] P,PropertyInfo pro) { if (P == null) throw new NullReferenceException("CopyHelper類中GetPropertyByName()方法參數PropertyInfo[]為Null"); var item = P.ToList().Find(x => x.Name.Equals(pro.Name) && (pro.PropertyType.IsSubclassOf(x.PropertyType) || pro.PropertyType.FullName.Equals(x.PropertyType.FullName))); return item; }
2、淺拷貝的主體方法,即調用上面的方法基礎上,如果不為空,並且允許寫入的話,則用SetValue方法進行賦值
/// <summary> /// 淺拷貝 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="vo">原始的VO</param> /// <param name="viewModel">VM下的vo</param> /// <returns></returns> private static T O2M<T>(object vo,T viewModel) { //獲取viewmodel的屬性集合 PropertyInfo[] VmPInfos = viewModel.GetType().GetProperties(); //獲取原始vo的屬性集合 PropertyInfo[] VoPInfos = vo.GetType().GetProperties(); for (int i = 0; i < VoPInfos.Length; i++) { //從VM中找到和VO中對應的屬性 var pro = VmPInfos.GetPropertyByName(VoPInfos[i]); //如果不為空,並且可以寫,則進行賦值 if (pro != null && pro.CanWrite) pro.SetValue(viewModel, VoPInfos[i].GetValue(vo, null), null); } return viewModel; } private static T O2M<T>(object vo) where T :new () { if (vo == null) return default(T); T viewModel = new T(); return O2M<T>(vo, viewModel); }
3、向外暴露一個擴展Copy方法,運行調用
/// <summary> /// 將字段名稱一致,類型一致的屬性賦值(用於ViewModel和Vo相互轉化) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="vo"></param> /// <returns></returns> /// <remarks>注意此賦值為淺拷貝,Model會重新new()</remarks> public static T CopyTo<T>(this object vo) where T :new() { return O2M<T>(vo); } /// <summary> /// 將字段名稱一致,類型一致的屬性賦值(用於ViewModel和Vo相互轉化) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="vo"></param> /// <returns></returns> /// <remarks>注意此賦值為淺拷貝,Model會重新new()</remarks> public static bool CopyTo<T>(this object vo,T model)where T :new () { if (model == null) model = new T(); return O2M<T>(vo, model) != null; }
二、測試
1、新建兩個實體類,HumanVo和StudentVo
public class HumanVo { private string _name; private int _age; private bool _sex; public string Name { get { return _name; } set { _name = value; } } public int Age { get { return _age; } set { _age = value; } } public bool Sex { get { return _sex; } set { _sex = value; } } }
public class StudentVo { private string _name; private int _age; private bool _sex; private string _class; private string _school; public string Name { get { return _name; } set { _name = value; } } public int Age { get { return _age; } set { _age = value; } } public bool Sex { get { return _sex; } set { _sex = value; } } public string Class { get { return _class; } set { _class = value; } } public string School { get { return _school; } set { _school = value; } } }
2、給HumanVo進行賦值
private void AddInfo() { HumanVo.Name = "李蕾"; HumanVo.Age = 16; HumanVo.Sex = true; }
3、調用CopyTo方法
HumanVo.CopyTo(StudentVo);
4、查看結果
調用方法之前,跟蹤代碼,看兩個VO的值
調用方法後,查看StudentVO的值