浅复制与深复制

 

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

 

posted @ 2013-02-18 17:35  Space Tian  阅读(194)  评论(0编辑  收藏  举报