• 通过属性进行浅拷贝


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

    一、方法体

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

  • 相关阅读:
    Elastic Search(一)
    嵌入式jetty
    mybatis中的#{}和${}的区别
    拦截器和过滤器的区别
    springboot对拦截器的支持
    Springboot对filter的使用
    springboot对监听器Listener的使用
    随机数的基本概念
    hashset和treeset区别
    java中常见的api方法记录
  • 原文地址:https://www.cnblogs.com/ZXdeveloper/p/5945628.html
Copyright © 2020-2023  润新知