记录一个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 }