C#中深拷贝和浅拷贝的例子

80酷酷网    80kuku.com

  

C#中有两种类型变量,一种是值类型变量,一种是引用类型变量。对于前者,copy是属于全盘复制;
而对于后者,一般的copy只是浅copy,相当于只传递一个引用指针一样。因此对于后者进行真正copy的时候,也是最费事的,具体的说,必须为其实现ICloneable接口中提供的Clone方法,示例代码如下:

public class Test
{    
    
public class Person : ICloneable
    {
        
public int ID;
        
public int age;
        
public void Show()
        {
            Console.WriteLine(
"ID:{0} 年龄:{1}",ID, age);
        }
        
public object Clone()
        {
            Person newPerson 
= new Person();
            newPerson.ID 
= this.ID;
            newPerson.age 
= this.age;      
            
return newPerson;
        }
    }
    
public static void ShowPersons(Person[] persons)
    {
        
for (int i=0; i<persons.GetLength(0); i++)
        {
            persons[i].Show();
        }
    }
    
static void Main(string[] argv)
    {
        Random rnd 
= new Random(unchecked((int)DateTime.Now.Ticks));
        Person[] persons 
= new Person[4];
        
for (int i=0;i<persons.GetLength(0);i++)
        {
            persons[i] 
= new Person();
            persons[i].ID 
= rnd.Next()%10;
            persons[i].age 
= rnd.Next()%50;
        }
        
//打印原始数组
        Console.WriteLine("打印原始数组");
        ShowPersons(persons);
        
//深拷贝
        Person[] personsCopied = new Person[4];
        
for (int i=0;i<personsCopied.GetLength(0);i++)
        {
            personsCopied[i] 
= (Person)persons[i].Clone();
        }
        
//persons.CopyTo(personsCopied, 0);
        Console.WriteLine("深拷贝的数组");
        ShowPersons(personsCopied);
//      //浅拷贝
//      Person[] personsCloned = (Person[])persons.Clone();
//      Console.WriteLine("浅拷贝的数组");
//      ShowPersons(personsCloned);
        
//对原数组做修改
        persons[2].ID += 10;
        Console.WriteLine(
"打印修改后的原始数组");
        ShowPersons(persons);
        Console.WriteLine(
"深拷贝的数组应该不改变");
        ShowPersons(personsCopied);
//      Console.WriteLine("浅拷贝的数组应该改变");
//      ShowPersons(personsCloned);
    }
}

某次的运行结果:

 

对于上例,在进行深拷贝时,必须先为对象数组new新的空间,而数组中的对象成员则由实现了接口的相应方法分配新的空间,由深拷贝出来的新对象数组不会因为原数组的改变而改变,相反,对于注释行中仅作了浅表复制的personsCloned而言则会受原数组的影响。

另外注意 persons.CopyTo(personsCopied, 0); 这一句并不是对personsCopied进行深表复制,数组直接拷贝是拷贝的指向同一个对象的引用,因为在C#中对于存放引用类型的数组,数组本身的引用类型和数组中元素的引用类型不能混为一谈,此时的数组仅相当于一个容器,所以对于容器本身和容器中存放的东西是要分别进行实例化的。呵呵困扰我很多天的问题贴上来做个备忘哈

分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: