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

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的深度克隆!

C#对象深度克隆的更多相关文章

  1. java对象 深度克隆(不实现Cloneable接口)和浅度克隆

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt128 为什么需要克隆: 在实际编程过程中,我们常常要遇到这种情况:有一个对象 ...

  2. JS对象深度克隆

    首先看一个例子: var student = { name:"yxz", age:25 } var newStudent = student; newStudent.sex = & ...

  3. js实现数组、对象深度克隆的两种办法

    1.深度克隆的原理 JS中的深度克隆,指的是原对象改变了,克隆出来的新对象也不会改变,原对象与新对象是完全独立的关系. 实现深度克隆的原理得从对象是一种引用类型说起 众所周知,对象是一种引用类型,对象 ...

  4. JavaScript对象之深度克隆

    也不知道从什么时候开始,前端圈冒出了个新词:对象深度克隆.看起来好像很高大上的样子,实际上并不新鲜,在我们的实际项目开发中,你可能早已用到,只不过由于汉字的博大精深,有些原本很简单的事物被一些看似专业 ...

  5. JavaScript实现对象的深度克隆及typeof和instanceof【简洁】【分享】

    JavaScript实现对象的深度克隆 代码实现如下: <!DOCTYPE html> <html lang="en"> <head> < ...

  6. js对象的深度克隆

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. javascript中对象的深度克隆

    记录一个常见的面试题,javascript中对象的深度克隆,转载自:http://www.2cto.com/kf/201409/332955.html 今天就聊一下一个常见的笔试.面试题,js中对象的 ...

  8. javascript最新深度克隆对象方法

    javascript最新深度克隆对象方法 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &qu ...

  9. java中传值及引伸深度克隆的思考(说白了Java只能传递对象指针)

    java中传值及引伸深度克隆的思考 大家都知道java中没有指针.难道java真的没有指针吗?句柄是什么?变量地址在哪里?没有地址的话简直不可想象! java中内存的分配方式有两种,一种是在堆中分配, ...

随机推荐

  1. java学习笔记之日期日历类

    java学习笔记之日期日历 Date日期类概述: 表示特定的瞬间,精确到毫秒 Date类的构造方法: 1.空参数构造方法 Date date = new Date(); 获取到当前操作系统中的时间和日 ...

  2. python学习第一天基础篇

    学习背景:决定开始学习python之前,因为公司基本都是微软系统,所以很少碰到linux系统,机缘巧合接到了一个项目是使用shell对mysql进行backup,因为公司唯一的系统工程师是微软在行,对 ...

  3. linux shell 推断文件或目录是否真的存在

    #推断文件或目录是否存在 filepath=/data/test.txt folderpath=/data/qtech #推断文件是否存在 if [ -f "$file" ] th ...

  4. 初识homebrew

    homebrew是MAC上的一个包管理工具,用于软件安装,非常方便. homebrew安装: 命令行执行: ruby -e "$(curl -fsSL https://raw.githubu ...

  5. 工厂方法模式的一些思考(java语法表示)

    同为创造型设计模式的简单工厂模式可以理解为对new关键字的代替. 本着重复三次即重构的原则,如果一个对象在不同的地方被new了两次以上,那就可以考虑使用它.那我们为什么要用简单工厂模式代替new呢?就 ...

  6. Java面向对象的特征

    面向对象的特征 封装.继承.多态.(有人问第四个特征,再加抽象) 封装 体现形式(2种) 函数---提高代码的复用性 属性的私有化---将属性设置为私有的,通过提供对外的访问方法来间接操作对应属性,可 ...

  7. CS:APP3e 深入理解计算机系统_3e Attacklab 实验

    详细的题目要求和资源可以到 http://csapp.cs.cmu.edu/3e/labs.html 或者 http://www.cs.cmu.edu/~./213/schedule.html 获取. ...

  8. Libevent源码分析 (1) hello-world

    Libevent源码分析 (1) hello-world ⑨月份接触了久闻大名的libevent,当时想读读源码,可是由于事情比较多一直没有时间,现在手头的东西基本告一段落了,我准备读读libeven ...

  9. vue使用国际化

    转载请注明作者与出处 一:安装vue-i18n npm install vue-i18n --save 二:定义不同语言的json语言包 一般把它放到npm工程中的src目录下,因为这个目录是要进行编 ...

  10. 【算法】论平衡二叉树(AVL)的正确种植方法

    参考资料 <算法(java)>                           — — Robert Sedgewick, Kevin Wayne <数据结构>       ...