浅复制与深复制
using System; using System.Linq; class Program { static void Main() { //~ 以下测试是使结构体s2=s1,然后修改s2的数据,观察对s1的影响 var s1=new S1(); s1.Title="I'm s1"; s1.firstPoint=new Point(0,0); s1.otherPoint=new Point[]{new Point(1,1),new Point(2,2)}; //~ 直接赋值,使s2=s1 //~ 显示数据完成相同 Console.WriteLine("TEST 1:"); var s2=s1; Console.WriteLine("s1: "+s1); Console.WriteLine("s2: "+s2); Console.WriteLine(); //~ 直接修改s2的值类型数据(firstPoint)和引用类型数据(otherPoint) //~ 值类型数据的改变不影响s1,引用类型数据的改变影响s1 Console.WriteLine("TEST 2:"); s2=s1; Console.WriteLine("s1: "+s1); s2.Title="I'm s2"; s2.firstPoint.x=50; s2.firstPoint.y=50; s2.otherPoint[0].x=150; s2.otherPoint[0].y=150; s2.otherPoint[1].x=250; s2.otherPoint[1].y=250; Console.WriteLine("s2: "+s2); Console.WriteLine("s1: "+s1); Console.WriteLine(); //~ 使用new更改变值类型(firstPoint)和引用类型(otherPoint) //~ 值类型改变不影响s1,引用类型改变没影响s1 Console.WriteLine("TEST 3:"); s2=s1; s2.Title="I'm s2"; Console.WriteLine("s1: "+s1); s2.firstPoint=new Point(-99,-98); s2.otherPoint=new Point[]{new Point(-1,-1),new Point(-2,-2)}; Console.WriteLine("s2: "+s2); Console.WriteLine("s1: "+s1); Console.WriteLine(); //~ otherPoint是个数组,s2=s1后,创建这个数组的副本 //~ s2.otherPoint的改变不再影响s1.otherPoint的改变 Console.WriteLine("TEST 4:"); s2=s1; s2.otherPoint=s1.otherPoint.ToArray(); //创建一个副本 s2.Title="I'm s2"; Console.WriteLine("s1: "+s1); s2.firstPoint.x=1; s2.firstPoint.y=2; s2.otherPoint[0].x=3; s2.otherPoint[0].y=4; s2.otherPoint[1].x=5; s2.otherPoint[1].y=6; Console.WriteLine("s2: "+s2); Console.WriteLine("s1: "+s1); //~ 结论:结构体对象中的引用类型,在结构体所在的栈中只保存了引用对象的引用(指针), //~ 使用简单赋值操作(s2=s1),不会在托管堆中创建引用对象的副本,它们将共同使用同一 //~ 引用对象。即,结构体的简单赋值操作(s2=s1)是对栈中结构体数据进行浅复制。 //~ 注:字符串对象System.String为特别的引用类型,具有值类型行为,因此,结论中的 //~ 引用对象不包含字符串类型对象。 } } //具有引用类型的结构体 struct S1 { public string Title; //字符串具体值类型行为 public Point firstPoint; //结体体是值类型 public Point[] otherPoint; //数组是引用类型 public override string ToString() { string otherPointStr=string.Empty; if(otherPoint!=null) { foreach(var item in otherPoint) { otherPointStr+=item; } } return string.Format("{0} {1}-{2}",Title,firstPoint,otherPointStr); } } //最简单的结构体 struct Point { public int x; public int y; public Point(int x,int y) { this.x=x; this.y=y; } public override string ToString() { return string.Format("({0},{1})",x,y); } }
1 >test 2 TEST 1: 3 s1: I'm s1 (0,0)-(1,1)(2,2) 4 s2: I'm s1 (0,0)-(1,1)(2,2) 5 TEST 2: 6 s1: I'm s1 (0,0)-(1,1)(2,2) 7 s2: I'm s2 (50,50)-(150,150)(250,250) 8 s1: I'm s1 (0,0)-(150,150)(250,250) 9 TEST 3: 10 s1: I'm s1 (0,0)-(150,150)(250,250) 11 s2: I'm s2 (-99,-98)-(-1,-1)(-2,-2) 12 s1: I'm s1 (0,0)-(150,150)(250,250) 13 TEST 4: 14 s1: I'm s1 (0,0)-(150,150)(250,250) 15 s2: I'm s2 (1,2)-(3,4)(5,6) 16 s1: I'm s1 (0,0)-(150,150)(250,250) 17 >Exit code: 0 Time: 0.225
引用地址:http://blog.csdn.net/oyi319/article/details/6320091