C#的深拷贝与浅拷贝 - chunlieater/chunlifeet GitHub Wiki

浅拷贝:把被复制对象的值类型拷贝一份给复制对象,但是引用类型则只拷贝地址给复制对象,也就是说浅拷贝后的两个对象的引用类型的成员变量是指向公用的地址。 一个对象想实现浅拷贝,只需要其类继承ICloneable接口,实现其中的Clone方法,在方法中调用MemberwiseClone()就行了。

  • public class Chunli:ICloneable

  • {

  • public string Name{set;get;}//值类型

  • public Rouchu rou{set;get;}//引用类型

  • public object Clone(){

  •   return this.MeverwiseClone();
    
  • }

  • }

  • static void Main(string[] args)

  • {

  • Chunli chunli1 = new chunli();

  • Chunli chunli2 = (Chunli)chunli1.Clone();// 调用浅拷贝

  • }

  • 深拷贝:在浅拷贝的基础上,所有引用类型的成员变量也会被复制过去,达到两者的所有变量都是复制之后的值。这需要用序列化来实现,把对象写到流中,写入的就是元对象的一个拷贝,再把它从流里都出来,就实现了深拷贝。想实现深拷贝的类和其成员变量都需要实现Serializable接口,否则无法实现序列化。

  • [Serializable]

  • public Class Chunli

  • {

  • public string Name{set;get;}
    
  • public Rouchu Rou{set;get;}
    
  • public Chunli DeepClone(){
    
  •    object obj = null;
    
  •    BinaryFormatter bf = new BinaryFormatter();
    
  •    MemorySteam ms;
    
  •    using(ms = new MemoryStream())
    
  •    {
    
  •       bf.Serialize(ms,this);
    
  •    }
    
  •    using(MemoryStream outputMs = new MemoryStream(ms.ToArray()))
    
  •    {
    
  •       BinaryFormatter outputBf = new BinaryFormatter();
    
  •       obj = outputBf.Deserialize(outputMs);
    
  •    }
    
  •    return (Chunli)obj;
    
  • }
    
  • }

  • [Serializable]

  • public Class Rouchu

  • {

  •  public Zaisha zai{set;get;}
    
  • }

  • [Serializable]

  • public Class Zaisha{}

  • static void Main(string[] args)

  • {

  • Chunli chunli1 = new Chunli();
    
  • Chunli chunli2 = chunli1.DeepClone();
    
  • }

上面的例子里 DeepClone函数也可以这么写 更简单:

public Chunli DeepClone(){

  •    object obj = null;
    
  •    using(MemorySteam ms = new MemoryStream())
    
  •    {
    
  •       BinaryFormatter bf = new BinaryFormatter();
    
  •       bf.Serialize(ms,this);
    
  •       ms.Seek(0,SeekOrigin.Begin);
    
  •       obj = (Chunli)bf.Deserialize(ms);
    
  •    }
    
  •    return (Chunli)obj;
    
  • }