ArrayList 的深复制与浅复制

时间:2022-08-23 14:39:36

ArrayList是我在C#里用得最多的一个数据结构。其使用简单,并且功能强大。ArrayList 的容量是根据需要自动扩展的,能动态建立各种数据格式的链表,以及对链表里面的元素进行添加、删除等操作。ArrayList的使用方法都比较简单,容易搞错的就是ArrayList的复制问题。

 

复制 ArrayList 的时候,使用 ArrayList.Clone() 方法复制出来的新 ArrayList 之中元素的值会随着源 ArrayList 中元素的值发生变化而一起改变。


MSDN的说法是:集合的浅表副本仅复制集合的元素(不论它们是引用类型还是值类型),但不复制引用所引用的对象。新集合中的引用与原始集合中的引用指向相同的对象。与之相对,集合的深层副本将复制这些元素以及由它们直接或间接引用的所有内容。
ArrayList.Clone() 返回值是 ArrayList 的浅表副本。

 

网上大多数的说法是,新建一个ArrayList实例,逐条复制 property,使用 for 实现:

  for (int i = 0; i < srcArraylist.Count; i++)
  {
      Class t = new Class();    // Class是类名
      // 下面这句,若类 Class 中若有很多 Property,就要写很多行
      t.property = (Class)srcArraylist[i].property;
      dstArraylist.Add(t);
  }

 

第二种方法是,我们知道,对于自定义的类,一般通过继承 ICloneable接口,重写 Clone() 方法来自己实现深拷贝。
因此如果类有继承 ICloneable 接口,也可以这么写:

 for (int i = 0; i < srcArraylist.Count; i++)
  
{
       
// Clone()返回类型为Object,因此还要转换
      dstArraylist.Add( (Class)( ((ICloneable)srcArraylist[i]).Clone() ) );
  } 

 

还有一种是通过另外让类实现 ISerializable 接口,通过序列化反序列化的方法实现:

MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms,srcArraylist); 
   // list1中元素的类要实现ISerializable接口
ms.Seek(0, SeekOrigin.Begin);
dstArraylist
= (ArrayList)bf.Deserialize(ms);

ms.close;

 

 参考:http://www.cnblogs.com/dz2345/archive/2008/02/08/1066085.html