有时候我们需要根据一个对象创建另外一个相同对象,也就是所谓的复制。复制又分为浅度复制(也有叫影子复制)和深度复制。
主要的差别是对于引用类型而言。
浅度复制对引用类型只复制引用,及复制后源引用与目标引用的引用类型是指向都一个对象,操作其中一个,另外一个也会受印像。
深度复制者源引用和目标引用对象的是两个不同的对象,操作互不影响。
浅度复制是直接完全把栈的内容拷贝一份而已。而深度复制把对应的堆内容也拷贝了一份。
浅度复制可以直接调用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: }.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
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
