C#深度复制和浅度复制

复制一个值变量很简单,新建一个变量然后将原来的变量赋值过去就行,但是复制一个引用变量这种方法是不行的,如果不明白为什么可以先看看这篇解释

引用类型变量和值类型变量在赋值时的不同

如果要复制一个引用类型的变量,比如说类,需要在类定义中继承ICloneable接口,并实现Clone方法,这是一个固定格式,下面看一个例子

 public class Test:ICloneable
{
public int Val;
public object Clone() => MemberwiseClone();
}

定义了一个Test类,继承ICloneable接口,实现Clone方法,实现Clone方法的格式是固定的,这里使用了简化写法,public object Clone() => MemberwiseClone();等于

public object Clone()
{
return MemberwiseClone();
}

这是C#提供的方法,按照这么写就对了,此时如果要复制一个Test类的引用变量,就可以这么写

Test t1 = new Test();
Test t2 = (Test)t1.Clone();

有一个引用类型变量t1,调用t1.Clone()会在堆中重新开辟一个内存空间,并且复制t1堆空间的值,然后会返回这个新空间的内存地址,因为Clone()方法返回类型是object,所以强制类型转换为Test,然后赋给Test类型的变量t2

这个过程,便是C#中的浅度复制(ShallowCopy),也有称为影子复制的

这个复制会存在一些问题,那就是一个引用类型中存在引用类型字段时,引用类型字段并不会也复制一份

public class Test:ICloneable
{
public int Val;
public Test2 Z = new Test2();
public object Clone()
{
return MemberwiseClone();
}
}
public class Test2
{
public int D;
}

这里定义了两个类,其中Test类中包含了一个Test2类型的引用类型变量Z,我们先看内存中怎样表示的

从这张图我们可以看到,当我们使用Clone对引用类型进行Clone时,只会复制堆空间的值,如果堆空间中有引用类型,在复制时就只单纯的复制了引用类型的堆空间地址,这样的后果就是虽然Clone得到了两个堆空间对象,但是堆空间对象中的字段却指向了同一个另外的空间地址,在某些情况下就会出现问题

所以

浅度复制:解决了直接使用赋值运算符时变量指向了同一个堆空间的问题(即Test t2 = t1的问题),但是只解决了一层,对于包含在内的堆空间中的成员的引用没有进一步解决(即t1.Z和t2.Z指向了同一个堆空间地址)

为了解决上述问题,就需要使用深度复制,深度复制的基本思路,就是在Clone方法中创建一个新的对象并使其内容与现有内容保持一致(其实是废话),我们甚至可以不用继承ICloneable,但是建议继承并使用Clone方法,这样可以保持方法名的一致性

至于怎么实现,可以自行思考(主要是我也在思考中)

所以这篇文章的主要内容是讲:C#提供的return MemberwiseClone();只是浅度复制,不会为引用成员创建新空间并将引用成员空间的值复制过去,只会复制引用成员的空间地址,需要注意

C#深度复制和浅度复制的更多相关文章

  1. .NET基础之深度复制和浅度复制

    之前一直没有搞清楚深度复制和浅度复制的区别到底在哪里,今天彻底把这个东西弄懂了,写出来与到家共勉. 如果大家不懂值类型和引用类型的区别,请先看http://www.cnblogs.com/Autumo ...

  2. c#学习笔记-深度复制 与浅度复制

    关于值类型和引用类型: 浅度复制(shallow copy)只复制值类型(char,int )的值,而对于引用类型不会复制,浅度复制可以通过派生于System.Object的MemberwiseClo ...

  3. 转载---Java集合对象的深度复制与普通复制

    原博文:http://blog.csdn.net/qq_29329775/article/details/49516247 最近在做算法作业时出现了错误,原因是没有弄清楚java集合的深度复制和浅度复 ...

  4. [No0000B9]C# 类型基础 值类型和引用类型 及其 对象复制 浅度复制vs深度复制 深入研究2

    接上[No0000B5]C# 类型基础 值类型和引用类型 及其 对象判等 深入研究1 对象复制 有的时候,创建一个对象可能会非常耗时,比如对象需要从远程数据库中获取数据来填充,又或者创建对象需要读取硬 ...

  5. 深度解析javascript中的浅复制和深复制

    原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null ...

  6. Java的深度克隆和浅度克隆

    说到克隆,其实是个比较简单的概念,跟现实生活正的克隆一样,复制一个一模一样的对象出来.clone()这个方法是从Object继承下来的,一个对象要实现克隆,需要实现一个叫做Cloneable的接口,这 ...

  7. List的深度copy和浅度拷贝

    List<Student> list= Arrays.asList( new Student("Fndroid", 22, Student.Sax.MALE, 180) ...

  8. Cloneable接口的作用与深度克隆与浅度克隆

    cloneable接口的作用 cloneable其实就是一个标记接口,只有实现这个接口后,然后在类中重写Object中的clone方法,然后通过类调用clone方法才能克隆成功,如果不实现这个接口,则 ...

  9. js中的深复制和浅复制

    在实际情况中经常会遇到对对象复制的问题.比如在处理项目中的一笔多结构的数据存储或者调用,这个时候你就要对对象(json)进行操作,而不同的操作根据不同的需求来定义.其中最常见最普遍的是对对象的复制,重 ...

随机推荐

  1. Educational Codeforces Round 89 (Rated for Div. 2) C Palindromic Paths

    题目链接:Palindromic Paths 题意: 给你一个n行m列的矩阵,这个矩阵被0或者1所填充,你需要从点(1,1)走到点(n,m).这个时候会有很多路径,每一条路径对应一个01串,你可以改变 ...

  2. Codeforces Round #479 (Div. 3) F. Consecutive Subsequence (DP)

    题意:给你一个长度为\(n\)的序列,求一个最长的\({x,x+1,x+2,.....,x+k-1}\)的序列,输出它的长度以及每个数在原序列的位置. 题解:因为这题有个限定条件,最长序列是公差为\( ...

  3. C# 程序运行时间计算

    https://www.cnblogs.com/dearzhoubi/p/9842452.html

  4. .NET 5学习笔记(10)——Entity Framework Core之切换SQLServer和SQLite

    上一篇我们梳理了CodeFist的一般流程,本篇我们讨论如何在一套代码中,支持SQL Server和SQLite的切换.同时从本篇开始,我们从.NET Core 3.1 迁移到.NET 5.相信.NE ...

  5. 国产网络损伤仪 SandStorm -- 什么是链路规则?

    "链路规则"是网络损伤仪SandStorm(又名弱网测试仪)里面非常重要的功能,主要用于不同仿真链路之间的选择. 如下图的所示:                           ...

  6. 国产网络损伤仪SandStorm -- 为什么数据流还是走Bypass链路?

    如果你在使用网络损伤仪SandStorm测试移动互联网的应用程序或者在仿真所谓"弱网测试"的时候,发现所有的数据流还是在走Bypass链路,并没有预期地走自己创建的仿真链路,那么你 ...

  7. SpringBoot 中使用 Swagger2 出现 whitelabel page error 解决方法

    今天使用Swagger最新版,在pom.xml引入 <dependency> <groupId>io.springfox</groupId> <artifac ...

  8. codeforces 1030D Vasya and Triangle【思维+gcd】

    题目:戳这里 题意:选出三个点构成三角形,要求面积为n*m/k. 解题思路:因为三个点的坐标都是正整数,根据三角形面积公式(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))/2=n* ...

  9. leetcode17 电话号码的字母组合 dfs

    就dfs吧.... 然后,我傻了.前一道题不用考虑空,这道题就要考虑.... 还有注意vector要引用传递 class Solution { public: void dfs(string temp ...

  10. 牛客多校第五场B generator1(十进制矩阵快速幂)题解

    题意: 已知 \(X_i = a * X_{i - 1} + b * X_{i - 2}\),现给定\(X_0,X_1,a,b\),询问\(X^n \mod p\),其中\(n <= 10^{1 ...