知识大全 C#浅拷贝与深拷贝区别
Posted 类型
篇首语:炒沙作縻终不饱,缕冰文章费工巧。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 C#浅拷贝与深拷贝区别相关的知识,希望对你有一定的参考价值。
C#浅拷贝与深拷贝区别 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
也许会有人这样解释C# 中浅拷贝与深拷贝区别
浅拷贝是对引用类型拷贝地址 对值类型直接进行拷贝
不能说它完全错误 但至少还不够严谨 比如 string 类型咋说?
其实 我们可以通过实践来寻找答案
首先 定义以下类型
int string enum struct class int[ ] string[ ]
代码如下
//枚举
public enum myEnum
_ = _ =
//结构体
public struct myStruct
public int _int;
public myStruct(int i)
_int = i;
//类
class myClass
public string _string;
public myClass(string s)
_string = s;
//ICloneable 创建作为当前实例副本的新对象
class DemoClass : ICloneable
public int _int = ;
public string _string = ;
public myEnum _enum = myEnum _ ;
public myStruct _struct = new myStruct( );
public myClass _class = new myClass( );
//数组
public int[] arrInt = new int[] ;
public string[] arrString = new string[] ;
//返回此实例副本的新对象
public object Clone()
//MemberwiseClone 返回当前对象的浅表副本(它是Object对象的基方法)
return this MemberwiseClone();
注意
ICloneable 接口 支持克隆 即用与现有实例相同的值创建类的新实例
MemberwiseClone 方法 创建当前 System Object 的浅表副本
接下来 构建实例A 并对实例A 克隆产生一个实例B
然后 改变实例B 的值 并观察实例A 的值会不会被改变
代码如下
class 浅拷贝与深拷贝
static void Main(string[] args)
DemoClass A = new DemoClass();
//创建实例A的副本 > 新对象实例B
DemoClass B = (DemoClass)A Clone();
B _int = ;
Console WriteLine( int \\t\\t A: B: A _int B _int);
B _string = ;
Console WriteLine( string \\t A: B: A _string B _string);
B _enum = myEnum _ ;
Console WriteLine( enum \\t\\t A: B: (int)A _enum (int)B _enum);
B _struct _int = ;
Console WriteLine( struct \\t A: B:
A _struct _int B _struct _int);
B _class _string = ;
Console WriteLine( class \\t\\t A: B:
A _class _string B _class _string);
B arrInt[ ] = ;
Console WriteLine( intArray \\t A: B:
A arrInt[ ] B arrInt[ ]);
B arrString[ ] = ;
Console WriteLine( stringArray \\t A: B:
A arrString[ ] B arrString[ ]);
Console ReadKey();
结果如下
从最后的输出结果 我们得知
对于内部的Class 对象和数组 则Copy 一份地址 [ 改变B 时 A也被改变了 ]
而对于其它内置的int / string / enum / struct / object 类型 则Copy 一份值
有一位网友说 string 类型虽然是引用类型 但是很多情况下 Net 把string 做值类型来处理 我觉得string 应该也是按照值类型处理的
这说明他对string 类型还不够了解
可以肯定的是 string 一定是引用类型 那它为什么是深拷贝呢?
如果你看一下string 类型的源代码就知道了
//表示空字符串 此字段为只读
public static readonly string Empty;
答案就在于 string 是 readonly 的 当改变 string 类型的数据值时 将重新分配了内存地址
下面引用一段网友的代码 Vseen[ Aloner ] 的个人陋见
public class Student
// 这里用 字段 其实应当是属性
public string Name;
public int Age;
//自定义类 Classroom
public Classroom Class;
浅拷贝 Student A 浅拷贝出 Student B Name和Age拥有新的内存地址 但引用了同一个 Classroom
深拷贝 Student A 浅拷贝出 Student B Name和Age拥有新的内存地址 并且A Classroom 的内存地址不等于 B Classroom
其实俗点讲 有点像
public object Clone()
Student B = new Student();
B Name = this Name;
B Age = this Age;
//浅拷贝
B Class = this Class;
//深拷贝
B Class = new Classromm();
B Class Name = this Class Name;
B Class Teacher = this Class Teacher;
//根据情况 对Teacher 进行判定要进行的是深拷贝 还是浅拷贝
浅拷贝 给对象拷贝一份新的对象
浅拷贝的定义 —— 只对值类型(或string)类型分配新的内存地址
深拷贝 给对象拷贝一份全新的对象
深拷贝的定义 —— 对值类型分配新的内存地址 引用类型 以及引用类型的内部字段分配的新的地址
我是这么定义的 浅拷贝 换汤不换药
注意
在 NET 程序中 应该避免使用 ICloneable 接口
因为通过该接口无法判断究竟是浅拷贝还是深拷贝 这会造成误解或误用
深拷贝应该复制该对象本身及通过该对象所能到达的完整的对象图 浅拷贝只复制对象本身(就是该对象所表示的在堆中的一块连续地址中的内容)
个人愚见
Clone 深层拷贝 拷贝到了指针指向的内存块的值
cha138/Article/program/net/201311/13157相关参考
PHP与C#的值类型指向区别 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! PH和C#的值拷贝区
1、DVD加装防拷贝管制系统,在商品DVD碟件及播放设备加入防连接拷贝的识别码。 2、加注地在代码,无论是DVD播放机还是碟机,必须加注合法销售及发行地区的识别代码,在 各个区域发行有软件产品采用
Java技巧:拷贝枚举器以加强效率 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 当一个代码段正
拷贝文件的Java源代码 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! //ClassCopyF
JAVA深层拷贝DeepCopy的使用详解 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!最近需要用
如何实现文件夹对文件夹的拷贝呢?如果文件夹里还有文件夹怎么办呢? 接下来我就将我的方法演示给一些初学者希望能够帮助你们! /* *CopyRightby */ packageco
一个实用的Delphi屏幕拷贝程序的设计 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Borl
ORACLE7用户之间数据拷贝的方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 大型数据库系
拷贝的SQLServer7数据库的恢复方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 在
电影制片厂制作电影后,销售电影母带和拷贝取得的收入,是否应缴纳增值税 根据《财政部、海关总署、国家税务总局关于支持文化企业发展若干税收政策问题的通知》(财税〔2009〕31号)规定,广播电影电视行政