• C# 对象的拷贝


    在程序设计中,我们有时希望得到现有一个对象的拷贝。
    拷贝有两种:
    (1)浅拷贝(也称浅表复制);(2)深拷贝(也称深度复制)
    1.浅拷贝
    表示将所有非引用数据类型从一个对象复制到另一个对象;如果原有对象包含对像引用,则复制对角引用(即是指当对象的字段值被拷贝时,字段的引用对象不会被拷贝)。形成拷贝后的对象与原对象会引用同一个值。
    值的改变:修改副本中的对象引用时,原始列表也将更改,但当修改非引用项时,原始项保持不变。

    如果希望自己的类型实现浅拷贝;可以像下面这样在方法中调用System.Object的受保护方法MemberwiseClone即可:

    public Object Clone()
    {
    return this.MemberwiseClone();
    }

    实例1:
    using System;

    namespace ConsoleApplication6
    {
    class ptest:ICloneable
    {
    private int _weight;
    private int _height;
    public int[] v = { 1, 2, 3 };
    public void Display()
    {
    foreach (int i in v)
    Console.Write(i + ", ");
    Console.WriteLine();
    }
    public int Weight
    {
    get
    { return _weight; }
    set
    { _weight = value; }
    }
    public int Height
    {
    get
    { return _height; }
    set
    { _height = value; }
    }
    public object Clone()
    {
    return this.MemberwiseClone();
    }
    }
    class test
    {
    public static void Main()
    {
    ptest pa = new ptest();
    pa.Height = 10;
    pa.Weight = 20;
    ptest pb = (ptest)pa.Clone(); //实现浅拷贝
    Console.WriteLine(pb.Weight.ToString());
    Console.WriteLine(pb.Height.ToString());
    pa.Display();
    pb.Display();
    pb.Height = 40;
    pa.v[0] = 40;
    Console.WriteLine(pa.Height.ToString());
    Console.WriteLine(pb.Height.ToString());
    pa.Display();
    pb.Display();
    }
    }
    }

    输出:
    第一行: 20
    第二行: 10
    第三行: 1,2,3
    第四行: 1,2,3
    第五行: 10
    第六行: 40
    第七行: 40,2,3
    第八行: 40,2,3

    代码说明: 第一行至第四行说明:实现了已实例化对象pa的浅拷贝对象pb,故pb拥有与pa一样的值,且指向同一个对象ptest

    第五行至第六行说明:浅拷贝对于修改非引用项(类型)时,原始项保持不变。故当改变pb.Height=40;后pa.Height仍为原来的值10;


    第七行至第八行说明:浅拷贝对于修改的对象引用项(类型)时,原始列表也将更改。故当改变引用类型 int [] v 的v[0]=40;后两个对象的int []V的值都会改变.


    2.深拷贝:是一种对对象实例中的引用对象也进行了拷贝的一种形式;如一个对象中有一个指向字符串的字段,并且我们对这个对象进行了深拷贝的话;将创建一个新的对象和一个新字符串,新对象将引用新的字符串字段。而且当我们对一个对象进行深拷贝后,两个对象将不会共享任何东西,改变任何一个对象对另一个对象不会产生任何影响。

    ex:

        using System;

    class DeepCopy : ICloneable
    {
      public int[] v = {1,2,3};

      // 默认构造函数
      public DeepCopy()
      {
      }

      // 供Clone方法调用的私有构造函数
      private DeepCopy(int[] v)
      {
        this.v = (int[])v.Clone();
      }

      public Object Clone()
      {
        // 构造一个新的DeepCopy对象,构造参数为
        // 原有对象中使用的 v
        return new DeepCopy(this.v);
      }

      public void Display()
      {
        foreach(int i in v)
          Console.Write( i + ", ");
        Console.WriteLine();
      }
    }

    class Client
    {
      public static void Main()
      {
        DeepCopy dc1 = new DeepCopy();
        DeepCopy dc2 = (DeepCopy)dc1.Clone();
        dc1.v[0] = 9;

        dc1.Display();  
        dc2.Display();
      }
    }
    这次在克隆的时候,不但克隆对象本身,连里面的数组字段一并克隆。因此,最终打印出来的dc1与dc2不同


       输出:

        9,2,3

        1,2,3       //当我们对一个对象进行深拷贝后,两个对象将不会共享任何东西,改变任何一个对象对另一个对象不会产生任何影响。

     

  • 相关阅读:
    学习进度第七周
    NABCD---生活日历
    学习进度第六周
    人月神话阅读笔记(3)
    人月神话阅读笔记(2)
    人月神话阅读笔记(1)
    石家庄地铁查询(双人项目)
    学习进度第五周
    学习进度第四周
    返回一个整数数组中最大子数组的和。(续2)---二维数组
  • 原文地址:https://www.cnblogs.com/todd/p/1228250.html
Copyright © 2020-2023  润新知