C# 之浅拷贝与深拷贝问题拙见(一)

时间:2021-05-20 19:53:12

最近学习了C#深浅拷贝的知识,并将所练习及认知整理如下。

在了解C#深浅拷贝之前,需要知道C#中值类型及引用类型的区别。简单来说,值类型就是基础类型(常见基本类型以及枚举及结构体类型);引用类型是指Object,类类型等。

而且例如“值类型赋值就是在栈区内内容拷贝,而引用类型赋值则是在堆区路径拷贝”这种理解也是不全面的。实际上,如果值类型作为引用类型的一个成员变量的话,那么它的赋值也将遵循路径拷贝这一事实。

我们让引用类型直接赋值,定义引用类型如下:

class person
    {
        public string name;
        public  int age;
        public pay personpay;
        public void setPersonPay(pay varpay)
        {
            personpay = varpay;
        }
    }
    class pay
    {
        public int basicSalary;//基本工资
        public int commission;//提成
    }

调用过程如下:

C# 之浅拷贝与深拷贝问题拙见(一)C# 之浅拷贝与深拷贝问题拙见(一)
 public  void simpleCopy()
        {
            person personA = new person ();
            pay payA = new pay();
            payA.basicSalary = 2000;
            payA.commission = 1500;

            personA.age = 25;
            personA.name = "Lucy";
            personA.setPersonPay(payA);

            MessageBox .Show (personA .name +"\n"+personA .age .ToString ()+"\n"
            +"\n" + personA.personpay.basicSalary.ToString() + "\n" + personA.personpay.commission.ToString());

            person personB = personA;

            MessageBox.Show(personB.name + "\n" + personB.age.ToString() + "\n"
                        + "\n" + personB.personpay.basicSalary.ToString() + "\n" + personB.personpay.commission.ToString());


        }
View Code

结果如下:

personA显示:

 C# 之浅拷贝与深拷贝问题拙见(一)       

personB 显示:

 C# 之浅拷贝与深拷贝问题拙见(一)

说明AB内容一致。我们再在刚才调用代码后加入修改B信息的几行代码,新加代码如下:

C# 之浅拷贝与深拷贝问题拙见(一)C# 之浅拷贝与深拷贝问题拙见(一)
person personA = new person ();
            pay payA = new pay();
            payA.basicSalary = 2000;
            payA.commission = 1500;

            personA.age = 25;
            personA.name = "Lucy";
            personA.setPersonPay(payA);

            MessageBox .Show (personA .name +"\n"+personA .age .ToString ()+"\n"
            +"\n" + personA.personpay.basicSalary.ToString() + "\n" + personA.personpay.commission.ToString());

            person personB = personA;

MessageBox.Show(personB.name + "\n" + personB.age.ToString() + "\n"
                             + "\n" + personB.personpay.basicSalary.ToString() + "\n" + personB.personpay.commission.ToString());
          
            personB.name = "Sam";
            personB.age = 29;
            personB.personpay.basicSalary = 5000;
            personB.personpay.commission = 8000;

//personB内容修改之后,重新显示AB信息
            MessageBox.Show(personA.name + "\n" + personA.age.ToString() + "\n"
                             + "\n" + personA.personpay.basicSalary.ToString() + "\n" + personA.personpay.commission.ToString());


            MessageBox.Show(personB.name + "\n" + personB.age.ToString() + "\n"
                             + "\n" + personB.personpay.basicSalary.ToString() + "\n" + personB.personpay.commission.ToString());
View Code

 

结果显示如下:

personA:

C# 之浅拷贝与深拷贝问题拙见(一)        

personB:

C# 之浅拷贝与深拷贝问题拙见(一)

personB内容修改之后,AB的内容显示如下:

personA:

C# 之浅拷贝与深拷贝问题拙见(一)                 

personB:

C# 之浅拷贝与深拷贝问题拙见(一)

其实还可以在A给B赋值之后,修改A的值,其结果也如上。

由此可见,当personB内容改变时,personA的内容也改变了。证明在默认的情况下,引用类型的赋值时,仅是复制了其引用(指针),AB指向同一处内存,故不管哪个变量修改该处内存的值,所有指向该处内存的变量值都将发生变化。

2017-01-14