常规利用反射进行克隆

   public static T CloneModel<T>(T oModel)
{
var oRes = default(T);
var oType = typeof(T); //create new obj
oRes = (T)Activator.CreateInstance(oType); //pass 1 property
var lstPro = oType.GetProperties();
foreach (var oPro in lstPro)
{
var oValue = oPro.GetValue(oModel,null);
oPro.SetValue(oRes, oValue, null);
} var lstField = oType.GetFields();
foreach (var oField in lstField)
{
var oValue = oField.GetValue(oModel);
oField.SetValue(oRes, oValue);
}
return oRes;
}

但是当你克隆的字段中有引用类型的时候并不能真正的拷贝出一个新的如list

因此在SetValue的时候 你需要进行深度拷贝

代码如下可直接使用

public static object DeepCopy(object obj)
{
if (obj == null)
return null;
Type type = obj.GetType(); if (type.IsValueType || type == typeof(string))
{
return obj;
}
else if (type.IsArray)
{
Type elementType = Type.GetType(
type.FullName.Replace("[]", string.Empty));
var array = obj as Array;
Array copied = Array.CreateInstance(elementType, array.Length);
for (int i = 0; i < array.Length; i++)
{
copied.SetValue(DeepCopy(array.GetValue(i)), i);
}
return Convert.ChangeType(copied, obj.GetType());
}
else if (type.IsClass)
{ object toret = Activator.CreateInstance(obj.GetType());
FieldInfo[] fields = type.GetFields(BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
object fieldValue = field.GetValue(obj);
if (fieldValue == null)
continue;
field.SetValue(toret, DeepCopy(fieldValue));
}
return toret;
}
else
throw new ArgumentException("Unknown type");
}

使用的话就是在SetValue时 的oValue进行DeepClone即可

 public static T CloneModel<T>(T oModel)
{
var oRes = default(T);
var oType = typeof(T); //create new obj
oRes = (T)Activator.CreateInstance(oType); //pass 1 property
var lstPro = oType.GetProperties();
foreach (var oPro in lstPro)
{
var oValue = oPro.GetValue(oModel,null);
oPro.SetValue(oRes, DeepCopy(oValue), null);
} var lstField = oType.GetFields();
foreach (var oField in lstField)
{
var oValue = oField.GetValue(oModel);
oField.SetValue(oRes, DeepCopy(oValue));
}
return oRes;
}

这样你就实现了深度拷贝

C# DeepClone 深拷贝的更多相关文章

  1. jquery深拷贝和浅拷贝

    var obj1 = { a: 1 };var obj2 = { b: {bbb: 2} };function Clone(){//浅拷贝 拷贝到obj1值会被改变 在一个栈中 $.extend(ob ...

  2. 【转】JS常用函数整合库 lutils

    lutils 此工具包是在 outils 的基础上,加上个人平时收集的代码片段进行的二次整合 outils的GitHub:https://github.com/proYang/outils/blob/ ...

  3. C# 深拷贝的具体代码的封装与调用

    先封装下实现方法: public class DeepClone { public static object CopyObject(Object obj) { if (obj == null) { ...

  4. Java对象的深拷贝和浅拷贝、集合的交集并集

    http://blog.csdn.net/lian_1988/article/details/45970927 http://www.cnblogs.com/yxnchinahlj/archive/2 ...

  5. 关于JavaScript的浅拷贝和深拷贝

    在 JS 中有一些基本类型像是Number.String.Boolean,而对象就是像这样的东西{ name: 'Larry', skill: 'Node.js' },对象跟基本类型最大的不同就在于他 ...

  6. C# 深拷贝通用方法

    C#深拷贝通用方法(引用类型的拷贝) /// <summary> /// 深度COPY /// </summary> /// <typeparam name=" ...

  7. JavaScript的深拷贝的实现

    JavaScript的数据类型 简单数据类型 string number boolean function null undefined 复杂数据类型 String Number Boolean Fu ...

  8. 编写高质量代码改善C#程序的157个建议[为类型输出格式化字符串、实现浅拷贝和深拷贝、用dynamic来优化反射]

    前言 本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html .本文主要学习记录以下内容: 建议13.为类型输出格式化字符串 建议14.正确实现浅拷贝和深 ...

  9. .net平台下深拷贝和浅拷贝

    在.net类库中,对象克隆广泛存在于各种类型的实现中,凡是实现了ICloneable接口的类型都具备克隆其对象实例的能力.所以本文讲述的深拷贝和浅拷贝也是在实现ICloneable接口的基础上进行的. ...

随机推荐

  1. Chrome/Chromium的实验性功能+扩展推荐,让你的Chrome/Chromium起飞!

    1 实验性功能 Chrome/Chromium内置了一些很酷的实验性功能,打开 chrome://flags 即可访问.打开这些实验性功能后,浏览器的使用体验会更好,这里Chrome的版本为80.0. ...

  2. Java8 Map computeIfAbsent方法说明

    // 方法定义 default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { . ...

  3. Day17_106_IO_利用Buffered和BufferWriter完成复制

    利用Buffered和BufferWriter完成复制 代码示例: 用BufferedReader 和 BufferWriter完成复制 import java.io.*; public class ...

  4. JVM小册(1)------jstat和Parallel GC日志

    JVM小册(1)------jstat和Parallel GC日志 一. 背景 在生产环境中,有时候会遇到OOM的情况,抛开Arthas 等比较成熟的工具以外,我们可以使用java 提供的jatat和 ...

  5. 1055 The World's Richest

    Forbes magazine publishes every year its list of billionaires based on the annual ranking of the wor ...

  6. Winamp栈溢出漏洞研究【转载】

    课程简介 Winamp是一款非常经典的音乐播放软件,它于上世纪九十年代后期问世.与现在音乐播放软件行业百家争鸣的情况不同,当时可以说Winamp就是听音乐的唯一选择了,相信那个时代的电脑玩家是深有体会 ...

  7. linux当前运行进程

    一:linux查询服务器服务进程 inux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照, 就是执行ps命令的那个时刻的 ...

  8. 第四部分 数据搜索之使用HBASE的API实现条件查询

    因为数据清洗部分需要用到Mapreduce,所以先解决hbase的问题,可以用命令先在hbase存一下简单的数据进行查询,之后只要替换数据就可以实现了原本功能 在看该部分前,确保Hase API看了, ...

  9. ppt技巧--字体变化

    常见字体搭配 Nordri Tools

  10. 【原创】JVM如何运行Java程序的?

    [Deerhang] 我们知道Java程序的运行是依赖于JVM虚拟机的,JVM类语言经过编译生成class字节码文件,字节码又经JVM进一步的编译生成机器码,最终运行在硬件上.那么JVM存在的意义是什 ...