Loading

通过属性进行浅拷贝

这两天看一个要离职同事交接的代码,看到一个浅拷贝的方法感觉挺好,在这里记录一下。

一、方法体

  是一个静态方法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的值

posted @ 2016-10-10 14:15  眾尋  阅读(537)  评论(0编辑  收藏  举报