当前位置: 首页 > news >正文

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第五节 引用类型复制问题及用克隆接口ICloneable修复

深入浅出图解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代替String+String+String+String…前者速度稍慢初始化耗多点内存但在大字符串操作上节省内存,后者速度稍快初始化简单但在大字符串操作上耗内存)。如果我们回头去看上面的图解中,你会发现Stirng类型在图中并不是一个针指向另一个内存对象,而是为了尽可能的简单,把它当成值类型来演示了。


总结

在实际工作中,当我们需要复制引用类型变量时,我们最好让它实现ICloneable接口。这样可以让引用类型模仿值类型的使用,从而防止意外的错误产生。你可以看到,慎重得理不同的类型非常重要,因为值类型和引用类型在内存中的分配是不同的。

译文连接:http://www.c-sharpcorner.com/UploadFile/rmcochran/chsarp_memory401152006094206AM/chsarp_memory4.aspx

原文连接:https://blog.csdn.net/leewhoee/article/details/16997323

相关文章:

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第五节 引用类型复制问题及用克隆接口ICloneable修复

深入浅出图解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) 第二节…...

python中基本元素的pop函数

python中基本元素的pop函数 一、列表List二、元组Tuple三、字典dict四、集合set 一、列表List pop() 根据索引删除并返回被删除的元素,索引默认为-1 a [1, 2, 3, 2, 5] b a.pop() # b5,默认返回最后一个值 print(b) b a.pop(2) # b3,返回a[2] pri…...

MPLS动态协议LDP配置示例

一、预习: MPLS是一种根据报文中携带的标签来转发数据的技术,两台LSR必须在它们之间转的数据 的标签使用上“达成共识”。LSR之间可以运行LDP来告知其他LSR本设备上的标签绑定信息,从而实现标签报文的正确转发。 LSR:Label Switch…...

JS调用栈:为何会栈溢出

JS调用栈:为何会栈溢出 JS调用栈什么是函数调用什么是栈在开发中利用调用栈栈溢出 JS调用栈 JavaScript 经常会出现一个函数中调用另外一个函数的情况,调用栈就是用来管理函数调用关系的一种数据结构,首先你要先弄明白函数调用和栈结构 什么…...

代码随想Day52 | 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

300.最长递增子序列 这道题目的重点在于动态数组的定义 dp[i]:以nums[i]为结尾的最长递增子序列,因为这样定义可以进行递推; 递推:j从0-i进行对比,如果nums[i]大于nums[j],dp[i]dp[j]1; 初始化…...

使用 pytest 相关特性重构 appium_helloworld

一、前置说明 在 pytest 基础讲解 章节,介绍了 pytest 的特性和基本用法,现在我们可以使用 pytest 的一些机制,来重构 appium_helloworld 。 appium_helloworld 链接: 编写第一个APP自动化脚本 appium_helloworld ,将脚本跑起来 代码目录结构: pytest.ini 设置: [pyt…...

猪目标检测数据集VOC格式600张

猪是一种常见的哺乳动物,通常被人们认为是肉食动物,但实际上猪是杂食性动物,以植物性食物为主,也有偶尔食肉的习性。猪的体型较大,圆胖的体型和圆润的脸庞使其显得憨态可掬。它们主要通过嗅觉来感知周围环境&#xff0…...

Pandas中concat的用法

Pandas中concat的用法 ​ pd.concat 是 pandas 库中的一个函数,用于将多个 pandas 对象(如 Series、DataFrame)沿指定轴进行合并连接。 pd.concat(objs, axis0, joinouter, ignore_indexFalse, keysNone, levelsNone, namesNone, verify_in…...

【C++】引用详解

前言 在学习C语言时,我们通常会遇到两个数交换的问题,为了实现这一功能,我们会编写一个经典的Swap函数,如下所示: void Swap(int *a, int *b) {int tmp *a;*a *b;*b tmp; } 然而,这个Swap函数看起来可…...

平时的一些思考内容

文章目录 阶乘位运算求概率 阶乘 阶乘是一很迷人的,刚开始的的变化还不是很大,到后面变化类似于直线上升的,不知道现实中哪些实例来表示阶乘。19的阶乘就已经超过了long了,在竞赛或者其他中要求2023或者很大数字的阶乘就需要考虑…...

AIGC时代下,结合ChatGPT谈谈儿童教育

引言 都2024年了,谈到儿童教育,各位有什么新奇的想法嘛 我觉得第一要务,要注重习惯养成,我觉得聊习惯养成这件事情范围有点太大了,我想把习惯归纳于底层逻辑,我们大家都知道,在中国式教育下&a…...

Java中的锁(一)

一、前言 在Java中,锁是用于多线程同步的重要概念。它可以保护共享资源,确保多个线程在访问共享资源时的数据一致性。 共享资源指的是多个线程同时对同一份资源进行访问 (读写操作),被多个线程访问的资源就称为共享资源。 如何保证多个线程访…...

CSS-SVG-环形进度条

线上代码地址 <div class"circular-progress-bar"><svg><circle class"circle-bg" /><circle class"circle-progress" style"stroke-dasharray: calc(2 * 3.1415 * var(--r) * (var(--percent) / 100)), 1000" …...

英语中修饰头发的形容词顺序是怎么样的(加补充)

一、英语描述发型 :漂亮长短形状颜色头发。 例如她有一头美丽的黑色的直发。She has beautiful long straight black hair.二、多个形容词修饰同一名词时的顺序是固定的&#xff0c;其顺序为&#xff1a;①冠词、指示代词、不定代词、物主代词②序数词基数词③一般性描绘形容词…...

python的WebSocket编程详解,案例群聊系统实现

1.websocket相关 1.1为什么要用websocket 如果有需求要实现服务端向客户端主动推送消息时&#xff08;比如聊天室&#xff0c;群聊室&#xff09;有哪几种方案 轮训&#xff1a;让浏览器每隔两秒发送一次请求&#xff0c;缺点&#xff1a;有延时&#xff0c;请求太多网站压力…...

flutter学习-day22-使用GestureDetector识别手势事件

文章目录 1. 介绍2. 使用2-1. 单击双击和长按2-2. 拖动和滑动2-3. 缩放 3. 注意点 1. 介绍 在 flutter 中&#xff0c;GestureDetector 是手势识别的组件&#xff0c;可以识别点击、双击、长按、拖动、缩放等手势事件&#xff0c;并且可以与子组件进行交互&#xff0c;构造函数…...

uni-app tabbar组件

锋哥原创的uni-app视频教程&#xff1a; 2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中...共计23条视频&#xff0c;包括&#xff1a;第1讲 uni…...

【Midjourney】Midjourney根据prompt提示词生成人物图片

目录 &#x1f347;&#x1f347;Midjourney是什么&#xff1f; &#x1f349;&#x1f349;Midjourney怎么用&#xff1f; &#x1f514;&#x1f514;Midjourney提示词格式 Midjourney生成任务示例 例1——航空客舱与乘客 prompt prompt翻译 生成效果 大图展示 细节大…...

Oracle 拼接字符串

语法 使用||拼接如果内容中有单引号&#xff0c;则可在该单引号前面再加一个单引号进行转义 例子 比如有一个业务是根据需要生成多条插入语句 select insert into des_account_des_role(des_account_id, roles_id) values( || id || , || (select id from des_role where wo…...

探究公有云中的巨人:深入分析大数据产品的架构设计

目录 一、服务器分类 二、公有云基础和产品 网络 vpc专有网络 弹性公网IP(Elastic IP)...

亚马逊云科技 re:Invent 2023 产品体验:亚马逊云科技产品应用实践 王炸产品 Amazon Q,你的 AI 助手

意料之中 2023年9月25日&#xff0c;亚马逊宣布与 Anthropic 正式展开战略合作&#xff0c;结合双方在更安全的生成式 AI 领域的先进技术和专业知识&#xff0c;加速 Anthropic 未来基础模型的开发&#xff0c;并将其广泛提供给亚马逊云科技的客户使用。 亚马逊云科技开发者社…...

并发编程大杀器,京东多线程编排工具asyncTool

一、简介 并发编程大杀器&#xff0c;京东多线程编排工具asyncTool&#xff0c;可以解决任意的多线程并行、串行、阻塞、依赖、回调的并行框架&#xff0c;可以任意组合各线程的执行顺序&#xff0c;带全链路执行结果回调。多线程编排一站式解决方案。 二、特点 多线程编排&am…...

【开源项目】智慧交通~超经典开源项目实景三维数字孪生高速

数字孪生高速运营管理平台&#xff0c;以提升高速公路管理水平和方便出行为主要目标&#xff0c;充分利用云计算、AI、大数据等&#xff0c;实现对高速公路控制、指挥、运营的智能化。飞渡科技以实景三维数据为基础&#xff0c;基于大数据、高分遥感、数据分析以及数据融合等前…...

udp多播/组播那些事

多播与组播 多播&#xff08;multicast&#xff09;和组播&#xff08;groupcast&#xff09;是相同的概念&#xff0c;用于描述在网络中一对多的通信方式。在网络通信中&#xff0c;单播&#xff08;unicast&#xff09;是一对一的通信方式&#xff0c;广播&#xff08;broad…...

C++ Qt开发:SqlRelationalTable关联表组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍SqlRelationalTable关联表组件的常用方法及灵…...

【LeetCode】修炼之路-0001-Two Sum(两数之和)【python】【简单】

前言 计算机科学作为一门实践性极强的学科,代码能力的培养尤为重要。当前网络上有非常多优秀的前辈分享了LeetCode的最佳算法题解,这对于我们这些初学者来说提供了莫大的帮助,但对于我这种缺乏编程直觉的学习者而言,这往往难以消化吸收。&#xff08;为什么别人就能想出这么优雅…...

秋招复习篇之代码规范

目录 前言 1、变量命名 2、代码空格 1&#xff09;操作符左右一定有空格&#xff0c; 2&#xff09;分隔符&#xff08;, 和;&#xff09;前一位没有空格&#xff0c;后一位保持空格&#xff0c;例如&#xff1a; 3&#xff09;大括号和函数保持同一行&#xff0c;并有一个空格…...

Docker:登录私有仓库\退出私有仓库

一、登录仓库 docker login : 登录到一个Docker镜像仓库&#xff0c;如果未指定镜像仓库地址&#xff0c;默认为官方仓库 Docker Hub 语法: docker login [OPTIONS] [SERVER] docker login -u 用户名 -p 密码 仓库名称 # 登入私有仓库 [rootlocalhost ~]# docker login --…...

与擎创科技共建一体化“数智”运维体系,实现数字化转型

小窗滴滴小编获取最新版公司简介 前言&#xff1a; 哈喽大家好&#xff0c;最近分享的互联网IT热讯大家都挺喜欢&#xff0c;小编看着数据着实开心&#xff0c;感谢大家支持&#xff0c;小编会继续给大家推送。 新岁即将启封&#xff0c;我们一年一期的运维干货年末大讲也要…...

开放网络+私有云=?星融元的私有云承载网络解决方案实例

在全世界范围内的云服务市场上&#xff0c;开放网络一直是一个备受关注的话题。相比于传统供应商的网络设备&#xff0c;开放网络具备软硬件解耦、云原生、可选组件丰富等优势&#xff0c;对云服务商和超大型企业有足够的吸引力。 SONiC作为开源的网络操作系统&#xff0c;使得…...

wordpress文件下载/某网站seo诊断分析和优化方案

刚开始一直没有找到该系列的第五篇博客,郁闷的要死,本打算重写的,看来没必要了.那这一篇就相当于小结第五篇和第六篇使用的样例. 所有的NDK都是在Linux系统下开发的,jni C或者CPP文件这一篇开始是在windosws7 VC6.0中开发的.所以下面的新建Android项目之类的都是在我的Ubuntu12…...

做网址导航网站/网络营销渠道的特点

最近项目有个需求&#xff0c;在微信小程序中跳转外部链接完成相关的操作&#xff0c;操作完成后返回微信小程序的相关页面。1、跳转外部链接(官方文档)1)入口//跳转到入口wx.navigateTo({url: ../out/out})2)app.json{"pages": ["pages/main/main","…...

中华网军事网/企业网站排名优化方案

北大MOOC——TF2.0笔记 以下是我的听课笔记&#xff0c;供以后回忆&#xff08;大多内容来自ppt&#xff09; 一.神经网络计算 1.人工智能三大学派 行为主义&#xff1a;感知-动作控制系统&#xff08;例如&#xff1a;行走&#xff0c;避障&#xff09; 符号主义&#xff1…...

个人网站创建平台要多少钱/如何添加百度指数

转自&#xff1a;http://ir.hit.edu.cn/~car/programming/rup/toolment/vqtfy/tm_vqtfy.htm#Step1 目的 本工具向导概括说明了如何使用 Rational Quantify 快速地查明 Visual C/C、Visual Basic、和 Java 程序中的性能瓶颈。要了解 Quantify 的详细信息&#xff0c;包括如何设计…...

企业网站开发注册/如何自己做一个网站

2019独角兽企业重金招聘Python工程师标准>>> <span style"color:grey">就像我们时不时的打开QQ&#xff0c;看看微信&#xff0c;在工作岗位上的职员们离不开邮件。工作安排得依靠邮件通知&#xff0c;任务完成情况得用邮件汇报&#xff0c;大量邮件…...

网站建设的维护与更新/宁波网站推广大全

应用场景我们开发的控制台应用&#xff0c;在运行阶段很有可能被用户CtrlC终止或是被用户直接关闭。如果我们不希望用户通过CtrlC终止我们的程序&#xff0c;就需要对CtrlC或关闭事件作处理。处理方法在.net平台下Console类有个CancelKeyPress事件可以处理CtrlC&#xff0c;不过…...