克隆对象的几种方法

  克隆对象在开发过程中经常会遇到,有些时候需要浅克隆,有些时候需要深克隆,具体它们之间有什么区别,以及实现方式有哪些,在这里总结一下。

  实现深克隆有以下几种方法。

手动

代码如下:

//手动复制
var user2 = new User
{
	Id = user1.Id,
	Name = new UserName
	{
		FirstName= user1.Name.FirstName,
		LastName= user1.Name.LastName
	}
};

反射

代码如下:

1 //反射
2 var user3 = user1.Copy() as User;

扩展方法:

 1 public static class DeepCopyHelper
 2 {
 3     public static object Copy(this object obj)
 4     {
 5         Object targetDeepCopyObj;
 6         Type targetType = obj.GetType();
 7         //值类型
 8         if (targetType.IsValueType == true)
 9         {
10             targetDeepCopyObj = obj;
11         }
12         //引用类型
13         else
14         {
15             targetDeepCopyObj = System.Activator.CreateInstance(targetType);   //创建引用对象
16             System.Reflection.MemberInfo[] memberCollection = obj.GetType().GetMembers();
17
18             foreach (System.Reflection.MemberInfo member in memberCollection)
19             {
20                 if (member.MemberType == System.Reflection.MemberTypes.Field)
21                 {
22                     System.Reflection.FieldInfo field = (System.Reflection.FieldInfo)member;
23                     Object fieldValue = field.GetValue(obj);
24                     if (fieldValue is ICloneable)
25                     {
26                         field.SetValue(targetDeepCopyObj, (fieldValue as ICloneable).Clone());
27                     }
28                     else
29                     {
30                         field.SetValue(targetDeepCopyObj, Copy(fieldValue));
31                     }
32
33                 }
34                 else if (member.MemberType == System.Reflection.MemberTypes.Property)
35                 {
36                     System.Reflection.PropertyInfo myProperty = (System.Reflection.PropertyInfo)member;
37                     MethodInfo info = myProperty.GetSetMethod(false);
38                     if (info != null)
39                     {
40                         object propertyValue = myProperty.GetValue(obj, null);
41                         if (propertyValue is ICloneable)
42                         {
43                             myProperty.SetValue(targetDeepCopyObj, (propertyValue as ICloneable).Clone(), null);
44                         }
45                         else
46                         {
47                             myProperty.SetValue(targetDeepCopyObj, Copy(propertyValue), null);
48                         }
49                     }
50
51                 }
52             }
53         }
54         return targetDeepCopyObj;
55     }
56 }

序列化

代码如下:

1 //序列化
2 var user4 = user1.DeepClone();

扩展方法:

 1 /// <summary>
 2 /// 深克隆
 3 /// 先序列化再反序列化
 4 /// </summary>
 5 /// <typeparam name="T"></typeparam>
 6 /// <param name="obj"></param>
 7 /// <returns></returns>
 8 public static T DeepClone<T>(this T obj) where T : class
 9 {
10     return obj != null ? obj.ToJson().FromJson<T>() : null;
11 }

其它还有使用表达式。

总结:

  1. 手动复制性能最好,但是遇到很复杂的类的时候,工作量很大。
  2. 反射和序列化比起来,序列化更简单。
时间: 2024-10-09 15:10:32

克隆对象的几种方法的相关文章

像素的存储方法、显式创建Mat对象的七种方法

一.像素的存储方法: 存储像素值需要指定颜色空间和数据类型.其中,颜色空间是指针对一个给定的颜色,如何组合颜色元素以对其编码. 最简单的颜色空间要属灰度级空间,只处理黑色和白色,对他们进行组合便可以产生不同程度的灰色. 对于彩色方式则有更多种类的颜色空间,但不论哪种方式都是把颜色分成三个或者四个基元素,通过组合基元素可以产 生所有的颜色.RGB颜色空间是最常见的一种颜色空间,这归功于它也是人眼内部构成颜色的方式.它的基色是红色.绿色 和蓝色,有时为了表明透明颜色也会加入第四个元素alpha. 颜

javascript生成对象的三种方法

/** js生成对象的三种方法*/ // 1.通过new Object,然后添加属性 示例如下: var people1 = new Object(); people1.name = 'xiaohailong01'; people1.age = 31; alert("name:" + people1.name + ", age:" + people1.age); // 2.直接接收json数据生成 var people2 = { name : 'xiaohailon

(转载)Java中如何遍历Map对象的4种方法

在Java中如何遍历Map对象 How to Iterate Over a Map in Java 在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都实现了Map接口,以下方法适用于任何map实现(HashMap, TreeMap, LinkedHashMap, Hashtable, 等等) 方法一 在for-each循环中使用entries来遍历 这是最常见的并且在大多数情况下也是最可取的遍历方式.在键值都需要时使用. Map<Integer,

php7实例化类有对象有两种方法

php7实例化类有对象有两种方法,下面给介绍具体两种方法 class Person{public $a="96net.com.cn";public function eat(){echo 'xxxx';} } 1,NEW 关键词实例化对象 $xm= new Person();或者$xm= new Person; 2, 类名字符串,把类名赋值给变量 $strs='Person'; $xm= new $strs(); 原文地址:https://blog.51cto.com/13959155

java克隆对象clone()的使用方法和作用

转自:997.html">http://www.okrs.cn/blog/news/?997.html 内容摘要 若需改动一个对象,同一时候不想改变调用者的对象.就要制作该对象的一个本地副本.这也是本地副本最常见的一种用途.若决定制作一个本地副本.仅仅需简单地使用clone()方法就可以.Clone是"克隆"的意思,即制作全然一模一样的副本.这种方法在基础类Object中定义成"protected"(受保护)模式. 但在希望克隆的不论什么衍生类中,必

Intent传递对象的两种方法

Android为intent提供了两种传递对象参数类型的方法 分别需要使实体类实现Serializable接口.Parcelable接口 首先我们要知道,传递对象,需要先将对象序列化 一.那么为什么要对象序列化 1.永久性保存对象,保存对象的字节序列到本地文件中: 2.用过序列化对象在网络中.进程间传递对象: 二.序列化对象什么时候实现Serializable接口,什么时候实现Parcelable接口接口 1.Parcelable不能使用将数据存储在磁盘上,因为Parcelable在外界有变化的

Android高手进阶教程(十七)之---Android中Intent传递对象的两种方法(Serializable,Parcelable)!

[转][原文] 大家好,好久不见,今天要给大家讲一下Android中Intent中如何传递对象,就我目前所知道的有两种方法,一种是Bundle.putSerializable(Key,Object);另一种是Bundle.putParcelable(Key, Object);当然这些Object是有一定的条件的,前者是实现了Serializable接口,而后者是实现了Parcelable接口,为了让大家更容易理解我还是照常写了一个简单的Demo,大家就一步一步跟我来吧! 第一步:新建一个andr

Android中Intent传递对象的两种方法(Serializable,Parcelable)

今天要给大家讲一下Android中 Intent中如何传递对象,就我目前所知道的有两种方法,一种是Bundle.putSerializable(Key,Object);另一种是 Bundle.putParcelable(Key, Object);当然这些Object是有一定的条件的,前者是实现了Serializable接口,而后者是实现了Parcelable接口,为了让大 家更容易理解我还是照常写了一个简单的Demo,大家就一步一步跟我来吧! 第一步:新建一个Android工程命名为Object

(六十四)Android中Intent传递对象的两种方法(Serializable,Parcelable)

转载自:http://blog.csdn.net/android_tutor/article/details/5740845 大家好,好久不见,今天要给大家讲一下Android中Intent中如何传递对象,就我目前所知道的有两种方法,一种是Bundle.putSerializable(Key,Object);另一种是Bundle.putParcelable(Key, Object);当然这些Object是有一定的条件的,前者是实现了Serializable接口,而后者是实现了Parcelable