定义

  1. 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
  2. 从一个对象中,复制一份成为新对象

代码演示

abstract class Prototype
{
    private string id;
    

    public Prototype(string id)
    {
        this.id = id;
    }
    
    public abstract Prototype Clone();

}

// 具体原型类
class ConcretePrototype: Prototype
{
      public ConcreteProtoType(string id): base(id) { }
      

      public override Prototype Clone()
      {
            return (Prototype)this.MemberwiseClone();
      }

}

// 客户端代码
void Main()
{
     ConcretePrototype c1 = new ConcretePrototype("CI");
     ConcretePrototype c2 = (ConcretePrototype)c1.Clone();
}


// System 命名空间下 ICloneable

class B: ICloneable
{
    public string Name { get; set; }

    public object Clone()
    {
        return (B)this.MemberwiseClone();
    }

}

class A: ICloneable
{
     private int id;
     public B Bi;     

     public A(int id)
     {
         this.id = id;
         Bi = new Bi();
     }
    
    public override Oject Clone()
    {
         //浅复制
         return (A)this.MemberwiseClone();
    
        //深复制
        A a = (A)this.MemberwiseClone();
           a.Bi = (B)Bi.MemberwiseClone();
           a.Bi = (B)B.Clone();
           return a;        
    }

}

MemberwiseClone

  • 该方法创建一个浅表副本,方法是创建一个新的对象,然后将当前对象的非静态字段复制到新的对象。

    • 如果字段是值类型,则执行字段的逐位副本。
    • 如果字段是引用类型,则会复制引用,但不会复制引用的对象;因此,原始对象及其复本引用相同的对象。

浅复制

  • 值类型,逐位复制
  • 引用类型,复制引用地址

深复制

  • 把引用类型的值指向新复制的对象

使用场景 和 好处

  1. 一般在初始化的信息不发生变化的情况下,克隆是最好的办法,即隐藏了创建细节,又是对性能大大的提高。
  2. 克隆不用使用构造函数,有些构造函数比较耗时,而是动态获得对象运行时的状态