c# 深拷贝与浅拷贝/深克隆与浅克隆

  首先描述一下拷贝的含义:拷贝就类似与复制,是为对象创建副本的技术。

c#中的拷贝分为深拷贝和浅拷贝。

 浅拷贝:主要分为两种情况来讨论:值类型和引用类型。对于值类型来说:浅拷贝,拷贝的是对象的值。对于引用类型来说:拷贝的是对象的引用地址。

一般情况下都建议继成ICloneable,显示表明类型可以拷贝,具体如下:

1
2
3
4
5
6
7
8
public class TestClone : ICloneable
{
    public int test { set; get; }
    public object Clone()
    {
        return this.MemberwiseClone();
    }
}

 

深拷贝:无论值类型还是引用类型,都是拷贝的对象的值。

深拷贝的实现方式:对于值类型来说,浅拷贝即是深拷贝。但是对于引用类型来说不一样,所以我们这里讨论的实现方式是对引用类型来说的。一般可以使用序列化,或者自定义方法,对每个对象进行复制。

 

注意:我们在浅拷贝时,对引用类型来说,拷贝的对象的引用,即旧对象的值改变,新对象的值也会改变,相反,新对象的值改变,旧对象的值也会改变。例如如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  public class TestClone : ICloneable
  {
      public string IDCard { set; get; }
      public bool testBool { set; get; }
 
      public List<int> testList { set; get; }
 
      public int test { set; get; }
      public object Clone()
      {
          return this.MemberwiseClone();
      }
  }
 
  static void Main(string[] args)
  {
      TestClone cloneOld = new TestClone();
      cloneOld.test = 1;
      cloneOld.testList = new List<int> { 1, 2 };
      cloneOld.testBool = true;
      TestClone cloneNew = (TestClone)cloneOld.Clone();
      Console.WriteLine(cloneOld.test);
      Console.WriteLine(cloneNew.test);
      Console.WriteLine(cloneOld.testList.Count);
      Console.WriteLine(cloneNew.testList.Count);
      Console.WriteLine(cloneOld.testBool);
      Console.WriteLine(cloneNew.testBool);
      Console.WriteLine("改变old的值");
      cloneOld.test = 100;
      cloneOld.testList = new List<int> { 1, 2 ,3,4,5};
      cloneOld.testBool = false;
      Console.WriteLine(cloneOld.test);
      Console.WriteLine(cloneNew.test);
      Console.WriteLine(cloneOld.testList.Count);
      Console.WriteLine(cloneOld.testList.Count);
      Console.WriteLine(cloneOld.testBool);
      Console.WriteLine(cloneNew.testBool);
}

  运行结果如下:

 

 从以上结果可以看出:

引用类型中的值类型在浅拷贝时,是拷贝的是对象的值。  

引用类型在浅拷贝时,拷贝的是对象的引用。

 

string类型的引用类型较为特殊,当浅拷贝时,是将对应的而引用拷贝给了新的对象,但是当旧对象的值发生改变时,新对象的值并不发生改变,因为在每次改变string的值是,都会创建一个新的string对象。即一旦创建了该string对象,就不能修改此对象的值了。

 

posted @   keke..lele  阅读(766)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示