定制相册哪个网站好,服装服饰设计网站,东港建站公司,天眼查公司注册信息深入浅出图解C#堆与栈 C# Heaping VS Stacking 第五节 引用类型复制问题及用克隆接口ICloneable修复 [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第一节 理解堆与栈](https://mp.csdn.net/mdeditor/101021023)[深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第二节… 深入浅出图解C#堆与栈 C# Heaping VS Stacking 第五节 引用类型复制问题及用克隆接口ICloneable修复 [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第一节 理解堆与栈](https://mp.csdn.net/mdeditor/101021023)[深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第二节 栈基本工作原理](https://mp.csdn.net/mdeditor/101022949#)[深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第三节 栈与堆值类型与引用类型](https://mp.csdn.net/mdeditor/101023885#)[深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第四节 参数传递对堆栈的影响 1](https://mp.csdn.net/mdeditor/101026168#)[深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第四节 参数传递对堆栈的影响 2](https://mp.csdn.net/mdeditor/101027584#)[深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第五节 引用类型复制问题及用克隆接口ICloneable修复](https://mp.csdn.net/mdeditor/101028008#)[深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第六节 理解垃圾回收GC提搞程序性能](https://mp.csdn.net/mdeditor/101029557#)堆中引用类型复制问题及用克隆接口ICloneable修复前言简介赋值不仅仅是赋值值类型测试 如果我们把Shoe换成引用类型呢**引用类型测试** 整理我们的代码特殊引用类型String总结 深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第一节 理解堆与栈
深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第二节 栈基本工作原理
深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第三节 栈与堆值类型与引用类型
深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第四节 参数传递对堆栈的影响 1
深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第四节 参数传递对堆栈的影响 2
深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第五节 引用类型复制问题及用克隆接口ICloneable修复
深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第六节 理解垃圾回收GC提搞程序性能
堆中引用类型复制问题及用克隆接口ICloneable修复
前言
虽然在.Net Framework 中我们不必考虑内在管理和垃圾回收(GC)但是为了优化应用程序性能我们始终需要了解内存管理和垃圾回收(GC)。另外了解内存管理可以帮助我们理解在每一个程序中定义的每一个变量是怎样工作的。 简介
这一节我们将介绍引用类型变量在堆中存储时会产生的问题同时介绍怎么样使用克隆接口ICloneable去修复这种问题。 赋值不仅仅是赋值
为了更清晰的阐述这个问题让我们测试一下在堆中存储值类型变量和引用类型变量时会产生的不同情况。 值类型测试
首先我们看一下值类型。下面是一个类和一个结构类型(值类型)Dude类包含一个Name元素和两个Shoe元素。我们有一个CopyDude()方法用来复制生成新Dude。
Dude类是一个复杂类型因为值 类型结构Shoe是它的成员 它们都将存储在堆中。 当我们执行下面的方法时 我们得到了期望的结果 如果我们把Shoe换成引用类型呢**
引用类型测试**
当我们把Shoe改成引用类型时问题就产生了。 执行同样上面的Main()方法结果改变了如下 这并不是我们期望的结果。很明显出错了看下面的图解 因为现在Shoe是引用类型而不是值类型当我们进行复制时仅是复制了指针我们并没有复制指针真正对应的对象。这就需要我们做一些额外的工作使引用类型Shoe像值类型一样工作。 很幸运我们有一个接口可以帮我们实现ICloneable。当Dude类实现它时我们会声明一个Clone()方法用来产生新的Dude复制类。译外话复制类及其成员跟原始类不产生任何重叠即我们所说的深复制) 看下面代码 在Clone()方法里我们创建了一个新的Shoe克隆所有引用类型变量复制所有值类型变量最后返回新的对象Shoe。有些既有类已经实现了ICloneable我们直接使用即可如String。因此我们直接使用Color.Clone()。因为Clone()返回object对象我们需要进行一下类型转换。 下一步我们在CopyDude()方法里用克隆Clone()代替复制 再次执行主方法Main() 我们得到了期望的结果 下面是图解
整理我们的代码
在实践中我们是希望克隆引用类型并复制值类型的。这会让你回避很多不易察觉的错误就像上面演示的一样。这种错误有时不易被调试出来会让你很头疼。
因此为了减轻头疼让我们更进一步清理上面的代码。我们让Dude类实现IConeable代替使用CopyDude()方法 在主方法Main()使用Dude.Clone() 最后得到期望的结果 特殊引用类型String
在C#中有趣的是当System.String 使用操作符“”时实际上是进行了克隆(深复制)。你不必担心你只是在操作一个指针它会在内存中创建一个新的对象。但是你一定要注意内存的占用问题(译外话比如为什么在一定情况下我们使用StringBuilder代替StringStringStringString…前者速度稍慢初始化耗多点内存但在大字符串操作上节省内存后者速度稍快初始化简单但在大字符串操作上耗内存)。如果我们回头去看上面的图解中你会发现Stirng类型在图中并不是一个针指向另一个内存对象而是为了尽可能的简单把它当成值类型来演示了。 总结
在实际工作中当我们需要复制引用类型变量时我们最好让它实现ICloneable接口。这样可以让引用类型模仿值类型的使用从而防止意外的错误产生。你可以看到慎重得理不同的类型非常重要因为值类型和引用类型在内存中的分配是不同的。
译文连接http://www.c-sharpcorner.com/UploadFile/rmcochran/chsarp_memory401152006094206AM/chsarp_memory4.aspx
原文连接https://blog.csdn.net/leewhoee/article/details/16997323