常规利用反射进行克隆

   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. manjaro 手动调节屏幕亮度

    1 问题描述 manjaro版本20.0,桌面XFCE,设置之类的地方没有屏幕亮度调节的功能. 2 解决方案 解决方案来自arch wiki. 亮度由ACPI内核模块控制,这个模块的接口在以下位置: ...

  2. linux 查看cpu型号、memory

    查看CPU信息(型号) [root@TX-220-60-211 supdev]# cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c 40 In ...

  3. Ambassador-04- Mapping 资源

    官方文档:https://www.getambassador.io/docs/latest/topics/using/intro-mappings/#resources Ambassador 通过Ma ...

  4. 抛弃vuex ,拥抱ts,手撸泛型Store<T>!

    前段时间学习了下vue3 和ts ,就尝试下做了个项目,结果发现vuex和ts几乎无法结合,越写越别扭,开始怀疑用ts就是自己给自己挖坑,然后加了几个vue相关的群,去抱怨了几句,得到大佬指点:你可以 ...

  5. 996. Number of Squareful Arrays

    Given an array A of non-negative integers, the array is squareful if for every pair of adjacent elem ...

  6. 【转】gitlab CI流水线配置文件.gitlab-ci.yml详解

    目录 GitLab CI流水线配置文件.gitlab-ci.yml详解 实验环境 GitLab CI介绍 .gitlab-ci.yml 配置参数 参数详解 script image services ...

  7. POJ3228二分最大流

    题意:       有n个点,每个点有两个权值,金子数量还有仓库容量,金子可以存在自己的仓库里或者是别的仓库里,仓库和仓库之间有距离,问所有金子都必须存到库里最大距离的最小是多少? 思路:       ...

  8. android Javah生成JNI头文件

    项目要用到c语言库,因此来学习下jni 首先是在cmd中使用javah,出现了javah不是内部或外部命令的错误提示,javah是jdk自带的工具,提示说明在系统环境变量中没有jdk的路径,或者配置错 ...

  9. Swift系列四 - 枚举

    适度给类型起别名能够让代码更加易懂,开发效率更高,可维护性更好. 一.typealias(别名) typealias用来给类型起别名. typealias Byte = Int8 typealias ...

  10. 【python】Leetcode每日一题-132模式

    [python]Leetcode每日一题-132模式 [题目描述] 给定一个整数序列:a1, a2, ..., an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j &l ...