一个快速克隆方法引出深浅拷贝说明

提供的代码是一个泛型扩展方法,用于对任意类型的对象T进行浅拷贝(shallow copy)。这个方法使用反射来调用对象的MemberwiseClone方法,该方法为所有字段(包括值类型和引用类型字段)创建新的副本,但不复制引用类型字段所引用的对象。换句话说,它执行的是一个成员级的克隆,对于引用类型的字段,它复制的是引用本身,而不是引用的对象。

下面是该方法的详细解释:

public static T Clone<T>(this T obj)  
{  // 获取obj的类型  Type type = obj.GetType();  // 查找名为"MemberwiseClone"的方法,该方法是非公共的(即受保护的或私有的),并且是实例方法  MethodInfo method = type.GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);  // 如果找到了这个方法,则调用它并传递obj作为参数(即原对象本身)  // 由于MemberwiseClone不需要任何参数,所以第二个参数是null  object clonedObj = method?.Invoke(obj, null);  // 将返回的object类型转换为泛型类型T,并返回  return (T)clonedObj;  
}

要使用这个方法,你只需在支持MemberwiseClone方法的任何对象上调用它。
在C#中,MemberwiseClone方法是定义在System.Object类中的受保护(protected)成员。这意味着所有在C#中定义的类都隐式地继承了这个方法,因为所有的类最终都继承自System.Object。由于MemberwiseClone是受保护的,它只能在当前类或其派生类中被直接调用。如果要在类的外部使用它,通常需要通过反射(如示例所示)或将其封装为公共方法。

MemberwiseClone方法创建一个当前对象的浅拷贝(shallow copy),它会复制对象的所有字段到新的对象上,但是如果字段是引用类型,则复制的只是引用,而不是引用的对象本身。因此,对于引用类型的字段,原始对象和克隆后的对象将共享相同的引用。

class MyClass  
{  public int MyProperty { get; set; }  public string AnotherProperty { get; set; }  
}  class Program  
{  static void Main()  {  MyClass original = new MyClass { MyProperty = 1, AnotherProperty = "Hello" };  MyClass cloned = original.Clone(); // 使用扩展方法克隆对象  Console.WriteLine(cloned.MyProperty); // 输出: 1  Console.WriteLine(cloned.AnotherProperty); // 输出: Hello  // 注意:如果MyClass中有引用类型的字段,这些字段在克隆对象中将仍然指向原始对象中的相同实例。  }  
}

需要注意的是,MemberwiseClone方法创建的是浅拷贝,这意味着如果对象包含引用类型的字段,那么这些字段在克隆后的对象中将仍然引用原始对象中的相同实例。如果你需要深拷贝(deep copy),即复制对象及其所有引用类型字段所引用的对象,那么你需要实现自定义的深拷贝逻辑,这通常涉及递归地复制对象的所有字段,并对引用类型字段进行深拷贝。

在C#中,实现深度克隆(深拷贝)的方法有多种。深度克隆不仅复制对象的值类型字段,还复制原对象中的对象,即完全创建新对象。以下是几种实现深度克隆的常见方法:

使用序列化与反序列化:
通过将对象序列化为一个中间格式(如JSON或XML),然后再从该格式反序列化回来,可以实现深度克隆。这种方法可以处理对象的复杂结构,包括嵌套的对象和集合。但是,它要求对象及其所有成员都是可序列化的,并且可能会受到序列化格式的限制。

使用自定义的递归拷贝方法:
通过递归地遍历对象的所有字段和属性,并为每个字段和属性创建新的副本,可以实现深度克隆。这种方法需要编写更多的代码,并且需要处理各种数据类型和复杂情况(如循环引用)。

使用第三方库:
有些第三方库提供了深度克隆的功能,可以简化深度克隆的实现。例如,AutoMapper、DeepCopy等库都提供了深度克隆的功能。

使用反射:
与MemberwiseClone方法类似,反射也可以用来实现深度克隆。通过反射获取对象的所有字段和属性,并递归地创建它们的副本,可以实现深度克隆。但是,这种方法性能较低,且代码复杂度高。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/535.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解析OceanBase v4.2函数索引进行查询优化

一、如何通过函数索引来进行查询优化 函数索引是一种优化查询的技术&#xff0c;其主要作用在于提升包含函数调用的查询语句的执行速度。当查询语句中包含函数调用时&#xff0c;数据库系统需要逐行执行函数计算&#xff0c;这无疑会增加查询的复杂性&#xff0c;导致查询速度…

【C语言】多字节字符、宽字符(涉及字符集和编码)

字符集、编码&#xff1a; 字符集&#xff1a;一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称&#xff0c;包括各国家文字、标点符号、图形符号、数字等。例如&#xff1a;ASCII、Unicode、GB2312、GBK、GB18030、BIG5(繁体中文) ... 编码方式&#xff1a;符号…

【Flutter】自动生成图片资源索引插件一:FlutterAssetRefGenerator

介绍 FlutterAssetRefGenerator 插件&#xff1a;windows上 点击生成图片索引按钮后&#xff0c;pubspec.yaml 会出现中文乱码&#xff0c;需要手动改乱码&#xff1b;mac上没问题。 优点&#xff1a;点击图标自动生成。 目录 介绍一、安装二、使用 一、安装 安装FlutterAsset…

移动端不居中问题/安卓和ios下line-height上下居中 css兼容问题

移动端开发过程&#xff0c;经常会写带0.5px边框角标类的样式&#xff0c;直接使用border设置0.5px边框&#xff0c;ios有些机型会出现显示不完整的情况。所以改用伪元素方法实现边框。代码如下&#xff1a; .comment-entry::after{content: ;position: absolute;left: 0;top: …

快速IO的方式|Java快读模板

处理IO的方式&#xff1a; 处理输入和输出的方式&#xff1a; C&#xff1a;cin / cout Java&#xff1a;Scanner / System.out 但是这两种有超时的风险 那么C处理方式&#xff1a;直接改为scanf / printf &#xff0c;也就是C语言中的读写方式 Java处理方式&#xff1a;准备一…

Python 中 + 和 += 赋值操作的性能比较

1. 问题背景 在 Python 中&#xff0c;我们可以通过 和 … 完成累加操作&#xff0c;在实际开发过程中我们一般会优先选择 &#xff0c;然而最近在对比 和 … 的性能时出现了 反而更慢的现象。因此&#xff0c;我们决定对此问题进行深入探讨。 2. 解决方案 为了准确地…

C语言---贪吃蛇(一)---准备工作

文章目录 前言1.Win32 API介绍1.1.Win32 API1.2. 控制台程序1.3.控制台屏幕上的坐标[COORD](https://learn.microsoft.com/zh-cn/windows/console/coord-str)1.4.[GetStdHandle](https://learn.microsoft.com/zh-cn/windows/console/getstdhandle)1.5.[GetConsoleCursorInfo](h…

视频太大怎么压缩变小?8种方法随时压缩视频大小

视频太大怎么压缩变小&#xff1f;视频压缩方式分为两种&#xff0c;有损压缩和无损压缩&#xff0c;什么是有损什么是无损压缩&#xff0c;什么时候视频用无损压缩更好&#xff1f;什么时候用有损压缩更好&#xff1f;如何调整视频参数实现基本无损压缩&#xff1f; 今天就借助…

九章云极DataCanvas AIDC OS智算操作系统正式发布,开启AI智算新纪元

4月18日&#xff0c;2024九章云极DataCanvas智算操作系统新品发布会于北京隆重召开&#xff0c;全新产品DATACANVAS AIDC OS智算操作系统&#xff08;以下简称AIDC OS&#xff09;正式官宣。AIDC OS以卓越的AI技术实力和AI基础软件为根基&#xff0c;以重新定义和突破传统为创新…

我独自升级崛起在哪里下载 我独自升级崛起一键下载方法极速体验

我独自升级崛起在哪里下载 我独自升级崛起一键下载方法极速体验 最近在游戏圈内爆火的一款游戏《我独自升级&#xff1a;崛起》是一款由韩国漫画改编而成的热门多人网络在线联机游戏&#xff0c;这款游戏是一款的角色扮演游戏&#xff0c;游戏有着引人入胜的剧情模式。玩家们…

Docker 入门指南:快速上手 Docker

Docker 是一种开源的容器化平台&#xff0c;它可以帮助开发者轻松地打包、发布和运行应用程序。本指南将介绍 Docker 的基本概念和常用操作&#xff0c;帮助你快速入门 Docker 技术。 1. 安装 Docker 首先&#xff0c;你需要在你的操作系统上安装 Docker。Docker 支持多种操作…

m4a转wav怎么转?3个简单的转换方法~

随着音频的迅猛发展&#xff0c;不同的音频文件格式应运而生&#xff0c;其中M4A和WAV都备受欢迎。M4A格式的兴起始于对音质和压缩效率的双重追求&#xff0c;而WAV则因其高保真特性而成为专业录音室的首选。 M4A格式的由来 M4A格式最初是由苹果公司引入的&#xff0c;旨在提供…

ZCC5080E USB 5V 输入 1A 双节锂电池充电管理 IC替代CS5080E

概要&#xff1a; ZCC5080E 是一款 5V USB 适配器输入&#xff0c;高精度双节锂离子电池充电管理芯片。具有0V充电功能&#xff0c;涓流充电、恒流充电、恒压充电和自动截止、自动再充等一套完整充电循环的充电管理芯片。芯片内部特设 9V 抗浪涌&#xff0c;芯片应用更安全可…

6、JVM-JVM调优工具与实战

前置启动程序 事先启动一个web应用程序&#xff0c;用jps查看其进程id&#xff0c;接着用各种jdk自带命令优化应用 Jmap 此命令可以用来查看内存信息&#xff0c;实例个数以及占用内存大小 jmap -histo 14660 #查看历史生成的实例 jmap -histo:live 14660 #查看当前存活的实…

探索人工智能绘图的奇妙世界

探索人工智能绘图的奇妙世界 人工智能绘图的基本原理机器之美&#xff1a;AI绘图作品AI绘图对艺术创作的影响未来展望与挑战图书推荐&#x1f449;AI绘画教程&#xff1a;Midjourney使用方法与技巧从入门到精通内容简介获取方式&#x1f449;搜索之道&#xff1a;信息素养与终身…

CSS 实现视差滚动效果

一、是什么 视差滚动&#xff08;Parallax Scrolling&#xff09;是指多层背景以不同的速度移动&#xff0c;形成立体的运动效果&#xff0c;带来非常出色的视觉体验 我们可以把网页解刨成&#xff1a;背景层、内容层、悬浮层 当滚动鼠标滑轮的时候&#xff0c;各个图层以不…

启明云端ESP32-S3+车载桥接器案例,能实现对车载产品集控

最近房车旅行很盛行&#xff0c;谁不想五一自驾游开车去外面玩&#xff1f;为了能提升用户体验&#xff0c;车企房车智能化升级越来越普遍&#xff0c;接下来小启给大家讲一个案例&#xff0c;启明云端ESP32-S3车载桥接器&#xff0c;感兴趣的可以看看。 一、ESP32-S3车载桥接器…

分享4款免费ai绘画工具!

随着人工智能技术的飞速发展&#xff0c;AI绘画工具已经逐渐走入了我们的日常生活。这些工具不仅能够简化绘画过程&#xff0c;更能让普通人体验到艺术创作的乐趣。今天&#xff0c;我们就来盘点一下那些值得一试的免费AI绘画工具&#xff0c;看看它们如何让我们的创作欲望得到…

说真的,项目经理不太需要PMP

事实上&#xff0c;很多成功的项目经理并没有PMP证书&#xff0c;但他们凭借丰富的项目经验和对项目管理的深入理解&#xff0c;成功完成了许多复杂的项目。 PMP是一个全球公认的项目管理专业认证&#xff0c;它代表了项目经理在项目管理理论和方法上的专业知识和技能。所以会…

如何在 Linux 和 Mac 终端命令中添加别名

在本文中&#xff0c;我们将探讨一种简单的技巧&#xff0c;可以节省您在终端中输入重复命令的时间。 作为开发者&#xff0c;我们花费大量时间在终端上执行命令。无论是浏览目录、运行脚本、更改 Node.js 版本还是版本控制命令&#xff0c;手动输入每个命令都是一项耗时的任务…