定义
- 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
 - 从一个对象中,复制一份成为新对象
 
代码演示
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
该方法创建一个浅表副本,方法是创建一个新的对象,然后将当前对象的非静态字段复制到新的对象。
- 如果字段是值类型,则执行字段的逐位副本。
 - 如果字段是引用类型,则会复制引用,但不会复制引用的对象;因此,原始对象及其复本引用相同的对象。
 
浅复制
- 值类型,逐位复制
 - 引用类型,复制引用地址
 
深复制
- 把引用类型的值指向新复制的对象
 
使用场景 和 好处
- 一般在初始化的信息不发生变化的情况下,克隆是最好的办法,即隐藏了创建细节,又是对性能大大的提高。
 - 克隆不用使用构造函数,有些构造函数比较耗时,而是动态获得对象运行时的状态