MemberwiseClone与Clone

克隆是创建作为当前实例副本的新对象。

克隆分为深度克隆和浅度克隆

深度克隆:会克隆当前实例的所有所有成员.

浅度克隆:只会克隆当前实例的所有值类型的.


浅度克隆Object类为我们提供了一个受保护的克隆方法MemberwiseClone()

深度克隆要我们自己实现

 

实现深度克隆的方式一般有2种...

 

 

我来创建2个类

 

 [Serializable]//这个标记是表示可以序列化这个类

   //Address类  有2个属性 Province 和City
   public class Address
   {

      private string _city; 

      public string City

      {

        get { return _city; }

        set { _city = value; }

       }

 

 

        private string _province;    

        public string Province

        {

           get { return _province; }

           set { _province = value; }

        }

      }

        

     //Person 类有3个属性  Name 、Age、Address 

     [Serializable]

     public class Person

     {

        private string _name;

        private int _age;

        private Address _address;
       

        public Person(string name,int age,Address address)

        {

           _name = name;

           _age = age;

           _address = address;
         }

          public Person()
          {

          }

           public Address Address

           {

              get { return _address; }
              set { _address = value; }
            }

           public string Name

           {

              get { return this._name; }
              set {this._name = value;}
            }

            public int Age

            {

               get { return _age; }

               set { _age = value; }

             }

   

         }


      BinaryFormatter bf = new BinaryFormatter();
      ms.Seek(0, SeekOrigin.Begin);
   

 
 


    

 

   

      

   我们现在来让Person实现克隆

 

   在Person类中加入

   public Person Clone()

   {

      MemoryStream ms = new MemoryStream();

      bf.Serialize(ms, this);

      ms.Seek(0, SeekOrigin.Begin);

      return (Person)bf.Deserialize(ms);
    }

    这个方法就可以实现克隆了

    这个方法是利用序列化和反序列化来实现克隆 比较方便但是类必须用[Serializable]标记可以序列化  

    令一种方式:

    public Person Clone()
    {

       Person temp = new Person();
       temp.Name = this.Name;
       temp.Age = this.Age;
       temp.Address.Province = this.Address.Province;
       temp.Address.City = this.Address.City;
       return temp;
     }

      这种方式容易出错 当一个类的成员过多时容易出错。当你要修改类的成员时,这个克隆方法也要修改 。

      建议用第序列化的方式来实现克隆。

     

   

      public Person Clone()
      {

        return this.MemberwiseClone();
      }

 

 

MemberwiseClone 方法创建一个浅表副本,具体来说就是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。

 

下面的代码就是演示这个问题:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace CloneDemo
{
    [Serializable]
    class DemoClass
    {
        public int i = 0;
        public int[] iArr = { 1, 2, 3 };

        public DemoClass Clone1()
        {
            return this.MemberwiseClone() as DemoClass;
        }

        public DemoClass Clone2()
        {
            MemoryStream stream = new MemoryStream();
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, this);
            stream.Position = 0;
            return formatter.Deserialize(stream) as DemoClass;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            DemoClass a = new DemoClass();
            a.i = 10;
            a.iArr = new int[] { 8, 9, 10 };
            DemoClass b = a.Clone1();
            DemoClass c = a.Clone2();

            // 更改 a 对象的iArr[0], 导致 b 对象的iArr[0] 也发生了变化
              a.iArr[0] = 88;


            Console.WriteLine("MemberwiseClone");
            Console.WriteLine(b.i);
            foreach (var item in b.iArr)
            {
                Console.WriteLine(item);
            }


            Console.WriteLine("Clone2");
            Console.WriteLine(c.i);
            foreach (var item in c.iArr)
            {
                Console.WriteLine(item);
            }

            Console.ReadLine();
        }
    }
}

 

      浅度克隆就很简单了 调用受保护的克隆方法MemberwiseClone()就可以了

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值