有时候我们需要根据一个对象创建另外一个相同对象,也就是所谓的复制。复制又分为浅度复制(也有叫影子复制)和深度复制。
主要的差别是对于引用类型而言。
浅度复制对引用类型只复制引用,及复制后源引用与目标引用的引用类型是指向都一个对象,操作其中一个,另外一个也会受印像。
深度复制者源引用和目标引用对象的是两个不同的对象,操作互不影响。
浅度复制是直接完全把栈的内容拷贝一份而已。而深度复制把对应的堆内容也拷贝了一份。
浅度复制可以直接调用System.Object.MemberwiseClone()这个受保护的方法就可以了。
而深度引用根据C#的规范实现ICloneable接口即可。
代码如下
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5:
6: namespace TestCopy
7: {
8: public class Element
9: {
10: public int member;
11: public Element(int member)
12: {
13: this.member = member;
14: }
15: public Element GetCopy()
16: {
17: return (Element)MemberwiseClone();
18: }
19: }
20: public class test : ICloneable
21: {
22: public Element tMember;
23:
24: public test(Element m)
25: {
26: tMember = new Element(m.member);
27: }
28:
29: public test GetCopy()
30: {
31: return (test)MemberwiseClone();
32: }
33:
34: public object Clone()
35: {
36: return new test(this.tMember);
37: }
38:
39: }
40: class Program
41: {
42: static void Main(string[] args)
43: {
44: Element e1 = new Element(10);
45: Element e2 = e1.GetCopy();
46: Console.WriteLine("{0},{1}",e1.member,e2.member);
47: e1.member = 11;
48: Console.WriteLine("{0},{1}", e1.member, e2.member);
49:
50: test t1 = new test(e2);
51: test t2 = t1.GetCopy();
52: test t3 = (test)t1.Clone();
53: Console.WriteLine("{0},{1},{2}",t1.tMember.member,t2.tMember.member,t3.tMember.member);
54: t1.tMember.member = 11;
55: Console.WriteLine("{0},{1},{2}", t1.tMember.member, t2.tMember.member, t3.tMember.member);
56: Console.ReadKey();
57: }
58: }
59:
60: }
Element是一个包含一个值类型的类。所以没有浅度复制与深度复制的差别
而test是一个包含有一个引用类型的类。t1是源对象,t2是用浅度复制出来的对象,t3是深度复制出来的对象。
根据运行结果可以发现,t1,t2的tMenmber字段其实是同一个东西。t3的tMember字段是和他们不同的。
差别就在于深度复制是有完全new一个新的对象出来的。
最后要提的是 深度复制是一个递归的过程。
假设现在又一个新类A包含一个test类型的字段。
对A设计深度复制时就要调用test的深度复制函数。
下面推荐两篇相关文章
http://hi.baidu.com/jinghao1/blog/item/6e13271a199ba4dcad6e75e3.html
http://blog.csdn.net/guchuanlong/archive/2010/04/30/5545068.aspx