这两天看一个要离职同事交接的代码,看到一个浅拷贝的方法感觉挺好,在这里记录一下。
一、方法体
是一个静态方法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的值