记录一个C#DeepCopy

简述

先来了解一下什么叫深拷贝

深拷贝:指的是拷贝一个对象时,不仅仅把对象的引用进行复制,还把该对象引用的值也一起拷贝。这样进行深拷贝后的拷贝对象就和源对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。比如一个黄狗叫大黄,使用克隆术克隆另外一个黄狗叫小黄,这样大黄和小黄就相对独立了,他们不互相影响。在.NET中int,double以及结构体和枚举等。int a=12;int c=a;//进行了深拷贝

c=232 //不影响

有深拷贝就必然有浅拷贝

浅拷贝:指的是拷贝一个对象时,仅仅拷贝对象的引用进行拷贝,但是拷贝对象和源对象还是引用同一份实体。此时,其中一个对象的改变都会影响到另一个对象。就像一个人改名了一样,他还是这个人,只不过名字变了而已。

 

 1 public class YDog
 2     {
 3         public string Name { get; set; }
 4     }
 5     class Program
 6     {
 7         static void Main(string[] args)
 8         {
 9             YDog sourceP = new YDog() { Name = "大黄" };
10             YDog copyP = sourceP; // 浅拷贝
11             copyP.Name = "小黄"; // 拷贝对象改变Name值
12             // 结果都是"小黄",因为实现的是浅拷贝,一个对象的改变都会影响到另一个对象
13             Console.WriteLine("YDog.Name: [SourceP: {0}] [CopyP:{1}]", sourceP.Name, copyP.Name);
14             Console.Read();
15         }
16     }

实现

在.Net 中可以有如下方法实现

1、新建一个对象,一个一个的重新赋值,麻烦一点

1 YDog Dog = new YDog() { Name = "大黄" };
2 YDog NewDog = new YDog() ;
3 NewDog .Name=Dog.Name

2、利用反射实现深拷贝

  

 1 /* 利用反射实现深拷贝*/
 2      public static object DeepCopy(object _object)
 3         {
 4             Type T = _object.GetType();
 5             object o = Activator.CreateInstance(T);
 6             PropertyInfo[] PI = T.GetProperties();
 7             for (int i = 0; i < PI.Length; i++)
 8             {
 9                 PropertyInfo P = PI[i];
10                 P.SetValue(o, P.GetValue(_object));
11             }
12             return o;
13         }

3、利用序列化和反序列化来实现,有两种方法,如下代码

 1 // 利用XML序列化和反序列化实现
 2         public static T DeepCopyWithXmlSerializer<T>(T obj)
 3         {
 4             object retval;
 5             using (MemoryStream ms = new MemoryStream())
 6             {
 7                 XmlSerializer xml = new XmlSerializer(typeof(T));
 8                 xml.Serialize(ms, obj);
 9                 ms.Seek(0, SeekOrigin.Begin);
10                 retval = xml.Deserialize(ms);
11                 ms.Close();
12             }
13 
14 
15             return (T)retval;
16         }
17 
18 
19         // 利用二进制序列化和反序列实现
20         public static T DeepCopyWithBinarySerialize<T>(T obj)
21         {
22             object retval;
23             using (MemoryStream ms = new MemoryStream())
24             {
25                 BinaryFormatter bf = new BinaryFormatter();
26                 // 序列化成流
27                 bf.Serialize(ms, obj);
28                 ms.Seek(0, SeekOrigin.Begin);
29                 // 反序列化成对象
30                 retval = bf.Deserialize(ms);
31                 ms.Close();
32             }
33 
34 
35             return (T)retval;
36         }

 

posted @ 2021-09-29 09:24  stweily  阅读(71)  评论(0编辑  收藏  举报