zoukankan      html  css  js  c++  java
  • C#对象深度克隆

    有基础的开发者都应该很明白,对象是一个引用类型,例如:

    object b=new object();

    object a=b;

    那么a指向的是b的地址,这样在有些时候就会造成如果修改a的值,那么b的值也会跟随着改变(a和b是同一个引用内存地址)。

    我们想要a和b都是各自互不影响的,那么只能是完全地新建一个新的对象,并且把现有对象的每个属性的值赋给新的对象的属性。也就是值类型的复制,这个操作就叫深度克隆。

    这里我们写两个泛型方法分别对对象T和集合List<T>进行深度克隆的实现,我们的方法实现方式是“扩展方法”,就是能在原有的对象后面直接“点”操作。

    下面我们来看一下深度克隆的算法实现:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Reflection;
    
    /**
     * author:qixiao
     * create:2017-5-25 11:52:21
     * */
    namespace QX_Frame.Helper_DG.Extends
    {
        public static class CloneExtends
        {
            public static T DeepCloneObject<T>(this T t) where T : class
            {
                T model = System.Activator.CreateInstance<T>();                     //实例化一个T类型对象
                PropertyInfo[] propertyInfos = model.GetType().GetProperties();     //获取T对象的所有公共属性
                foreach (PropertyInfo propertyInfo in propertyInfos)
                {
                    //判断值是否为空,如果空赋值为null见else
                    if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                    {
                        //如果convertsionType为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
                        NullableConverter nullableConverter = new NullableConverter(propertyInfo.PropertyType);
                        //将convertsionType转换为nullable对的基础基元类型
                        propertyInfo.SetValue(model, Convert.ChangeType(propertyInfo.GetValue(t), nullableConverter.UnderlyingType), null);
                    }
                    else
                    {
                        propertyInfo.SetValue(model, Convert.ChangeType(propertyInfo.GetValue(t), propertyInfo.PropertyType), null);
                    }
                }
                return model;
            }
            public static IList<T> DeepCloneList<T>(this IList<T> tList) where T : class
            {
                IList<T> listNew = new List<T>();
                foreach (var item in tList)
                {
                    T model = System.Activator.CreateInstance<T>();                     //实例化一个T类型对象
                    PropertyInfo[] propertyInfos = model.GetType().GetProperties();     //获取T对象的所有公共属性
                    foreach (PropertyInfo propertyInfo in propertyInfos)
                    {
                        //判断值是否为空,如果空赋值为null见else
                        if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                        {
                            //如果convertsionType为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
                            NullableConverter nullableConverter = new NullableConverter(propertyInfo.PropertyType);
                            //将convertsionType转换为nullable对的基础基元类型
                            propertyInfo.SetValue(model, Convert.ChangeType(propertyInfo.GetValue(item), nullableConverter.UnderlyingType), null);
                        }
                        else
                        {
                            propertyInfo.SetValue(model, Convert.ChangeType(propertyInfo.GetValue(item), propertyInfo.PropertyType), null);
                        }
                    }
                    listNew.Add(model);
                }
                return listNew;
            }
        }
    }

    上述代码已经实现了深度克隆的操作,在使用上我们如下:

    例如有User类,我们可以这样操作

    User user1=new User();

    User user2=user1.DeepCloneObject();

    这样就完成了对user1的深度克隆!

    本文为七小站主原创作品,转载请注明出处:http://www.cnblogs.com/7tiny/ 且在文章页面明显位置给出原文链接。

    作者信息(详情):

    QiXiao_柒小(東)
    Software Development
    北京市海淀区 Haidian Area Beijing 100089,P.R.China
    郵箱Email : seventiny@foxmail.com  
    網址Http: http://www.7tiny.com
    QQ:1124999434 , WeChat: wd8622088 (尽量加微信)
    (专好结交天下英雄好汉,可聊天,可谈技,可约饭,可..嗯,原则是要有的~) 更多联系方式点我哦~


    Best Regard ~
  • 相关阅读:
    centos7.6 使用yum安装mysql5.7
    解决hadoop本地库问题
    docker-compose 启动警告
    docker 安装zabbix5.0 界面乱码问题解决
    docker 部署zabbix问题
    zookeeper 超时问题
    hbase regionserver异常宕机
    (转载)hadoop 滚动升级
    hadoop Requested data length 86483783 is longer than maximum configured RPC length
    zkfc 异常退出问题,报错Received stat error from Zookeeper. code:CONNECTIONLOSS
  • 原文地址:https://www.cnblogs.com/7tiny/p/7007291.html
Copyright © 2011-2022 走看看