知识大全 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#的值类型指向区别

PHP与C#的值类型指向区别  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  PH和C#的值拷贝区

DVD碟片为什么不容易被拷贝?

1、DVD加装防拷贝管制系统,在商品DVD碟件及播放设备加入防连接拷贝的识别码。  2、加注地在代码,无论是DVD播放机还是碟机,必须加注合法销售及发行地区的识别代码,在  各个区域发行有软件产品采用

知识大全 拷贝枚举器以加强效率

Java技巧:拷贝枚举器以加强效率  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  当一个代码段正

知识大全 拷贝文件的Java源代码

拷贝文件的Java源代码  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  //ClassCopyF

知识大全 JAVA 深层拷贝 DeepCopy的使用详解

JAVA深层拷贝DeepCopy的使用详解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!最近需要用

知识大全 利用java本地拷贝文件及文件夹

  如何实现文件夹对文件夹的拷贝呢?如果文件夹里还有文件夹怎么办呢?    接下来我就将我的方法演示给一些初学者希望能够帮助你们!    /*  *CopyRightby  */  packageco

知识大全 一个实用的Delphi屏幕拷贝程序的设计

一个实用的Delphi屏幕拷贝程序的设计  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Borl

知识大全 ORACLE7 用户之间数据拷贝的方法

ORACLE7用户之间数据拷贝的方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  大型数据库系

知识大全 拷贝的SQL Server 7数据库的恢复方法

拷贝的SQLServer7数据库的恢复方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!    在

销售电影母带和拷贝取得的收入是否应缴纳增值税?

电影制片厂制作电影后,销售电影母带和拷贝取得的收入,是否应缴纳增值税  根据《财政部、海关总署、国家税务总局关于支持文化企业发展若干税收政策问题的通知》(财税〔2009〕31号)规定,广播电影电视行政