.NET中的Object类学习3_MemberwiseClone方法
文章目录
- 一、前言
- 二、Object.MemberwiseClone方法
- 1 定义
- 2 示例
- 3 备注
- 三、总结
一、前言
按照MSDN文档的章节顺序来,本文应该是第五节。
但是学了上一节 Finalize之后,发现其内容对实际开发帮助不大。
所以这次跳过了前面的GetHashCode、GetType章节,直接来到MemberwiseClone。因为拷贝操作相对来讲还是比较常用的。
二、Object.MemberwiseClone方法
1 定义
名称空间:System
程序集:System.Runtime.dll
创建一个当前对象的浅拷贝(shallow copy)(副本)。
// 返回值 Object 当前对象的一个浅拷贝
protected object MemberwiseClone();
注意
关于浅拷贝这个词,既可以做名词也可以做动词,作名词指一份浅拷贝的副本(浅拷贝操作后生成的对象);作动词就是指浅拷贝操作。
2 示例
以下示例说明了 MemberwiseClone 方法。它定义了一个 ShallowCopy 方法,该方法调用 MemberwiseClone 方法对 Person 对象执行浅拷贝操作。它还定义了一个 DeepCopy 方法,用于对 Person 对象执行深拷贝操作。
using System;public class IdInfo
{public int IdNumber;public IdInfo(int IdNumber){this.IdNumber = IdNumber;}
}public class Person
{public int Age;public string Name;public IdInfo IdInfo;public Person ShallowCopy(){return (Person) this.MemberwiseClone();}public Person DeepCopy(){Person other = (Person) this.MemberwiseClone();other.IdInfo = new IdInfo(IdInfo.IdNumber);other.Name = String.Copy(Name);return other;}
}public class Example
{public static void Main(){// 创建一个Person实例,并给它的字段分配一个值Person p1 = new Person();p1.Age = 42;p1.Name = "Sam";p1.IdInfo = new IdInfo(6565);// 执行一次p1的浅拷贝,将结果给p2Person p2 = p1.ShallowCopy();// 显示p1、p2的值Console.WriteLine("Original values of p1 and p2:");Console.WriteLine("p1 instance values:");DisplayValues(p1);Console.WriteLine("p2 instance values:");DisplayValues(p2);// 修改p1属性值,并显示p1、p2的值p1.Age = 32;p1.Name = "Frank";p1.IdInfo.IdNumber = 7878;Console.WriteLine("\nValues of p1 and p2 after changes to p1:");Console.WriteLine("p1 instance values:");DisplayValues(p1);Console.WriteLine("p2 instance values:");DisplayValues(p2);// 对p1做深拷贝,且结果分配给p3Person p3 = p1.DeepCopy();// 修改p1的成员值,并展示深拷贝的结果p1.Name = "George";p1.Age = 39;p1.IdInfo.IdNumber = 8641;Console.WriteLine("\nValues of p1 and p3 after changes to p1:");Console.WriteLine("p1 instance values:");DisplayValues(p1);Console.WriteLine("p3 instance values:");DisplayValues(p3);}public static void DisplayValues(Person p){Console.WriteLine("Name:{0:s}, Age:{1:d}", p.Name, p.Age);Console.WriteLine("Value:{0:d}", p.IdInfo.IdNumber);}
}// 示例输出如下:
// Original values of p1 and p2:
// p1 instance values:
// Name:Sam, Age:42
// Value:6565
// p2 instance values:
// Name:Sam, Age:42
// Value:6565// Values of p1 and p2 after changes to p1:
// p1 instance values:
// Name:Frank, Age:32
// Value:7878
// p2 instance values:
// Name:Sam, Age:42
// Value:7878// Values of p1 and p3 after changes to p1:
// p1 instance values:
// Name:George, Age:39
// Value:8641
// p3 instance values:
// Name:Frank, Age:32
// Value:7878
该例中,Person.IdInfo 属性返回一个 IdInfo 对象。如示例输出所示,调用 MemberwiseClone 方法克隆 Person 对象时,克隆的 Person 对象是原对象的独立备份,除了它们共享同一个 Person.IdInfo 对象引用外。因此,修改克隆对象的 Person.IdInfo 属性会更改原对象的 Person.IdInfo 属性。另一方面,当执行深拷贝操作时,修改克隆的 Person 对象,包括其 Person.IdInfo 属性,都不会影响到原对象。
3 备注
MemberwiseClone 方法通过创建一个新对象来创建浅拷贝,然后将当前对象的 非静态字段(nonstatic field)拷贝到新对象。若字段是值类型,则对该字段执行逐位复制(bit-by-bit copy)。若字段是引用类型,则引用会被复制,但引用的对象不会被复制;因此,原对象和其克隆引用的是同一个对象。
举个例子,
考虑一个名为X的对象,它引用了对象 A 和 B,对象 B 引用对象 C 。
X的浅拷贝创建了一个新对象X2,该对象也引用了对象 A 和 B 。
X的深拷贝创建了一个新对象X2,该对象引用新对象 A2 和 B2,它们是 A 和 B 的副本(副本意味着内容相同,但不是同一份,一式两份),依次引用了新对象 C2,C2 是 C 的副本。
该示例说明了浅拷贝与深拷贝操作之间的区别。
若 MemberwiseClone 方法执行的浅拷贝方法未能满足你的需求,有多种方法可以实现深拷贝操作。它们包括:
- 调用要复制的对象的类构造函数,用从第一个对象获取的属性值来创建第二个对象。这里假设对象的值完全由其类构造函数定义。
- 调用 MemberwiseClone 方法创建对象的浅拷贝,然后以原对象相同的值分配给新对象中的引用类型字段和属性。示例中的 DeepCopy 方法演示的就是该方式。
- 将深拷贝的对象序列化,然后将序列化后的数据恢复到不同的对象变量中。
- 使用反射和递归来执行深拷贝操作。
序列化和反射的方法涉及其它技术,有需要时另开一篇文详解。
三、总结
这节在概念上很简单,
- MemberwiseClone只复制对象,并返回对副本的一个引用。
- 浅拷贝是复制了类中所有值类型,若类包含引用类型的字段或属性,就只复制引用,而不复制引用的对象。
- 深拷贝除了复制类中值类型,还会对引用类型做特殊处理,对其引用的对象创建副本并赋予原对象中相同的值。
相关文章:
.NET中的Object类学习3_MemberwiseClone方法
文章目录 一、前言二、Object.MemberwiseClone方法1 定义2 示例3 备注 三、总结 一、前言 按照MSDN文档的章节顺序来,本文应该是第五节。 但是学了上一节 Finalize之后,发现其内容对实际开发帮助不大。 所以这次跳过了前面的GetHashCode、GetType章节&a…...
鼎捷前端开发校招岗技术面面经(已过)
前言 鼎捷一共两面,一面针对技术,这篇博客记录下我认为有价值的问题。 有价值的提问 js类的继承的方式 es5,涉及到原型、原型链的继承; es6,类与对象,extends,super; 还问到Vue…...
Rockchip平台rk3588源码下载编译(基于Android13)
Rockchip平台rk3588源码下载编译(基于Android13) 源码下载 下载地址 repo init --repo-url https://gerrit.rock-chips.com:8443/repo-release/tools/repo -u https://gerrit.rock-chips.com:8443/Android_T/manifests.git -m Android13.xml服务器镜像下载 repo init --rep…...
RuntimeError: PyPI no longer supports ‘pip search‘ (or XML-RPC search).
RuntimeError: PyPI no longer supports ‘pip search’ (or XML-RPC search). 1. ERROR: XMLRPC request failed Deprecated Methods https://warehouse.pypa.io/api-reference/xml-rpc.html#deprecated-methods PyPI XMLRPC Search Disabled https://status.python.org/inc…...
21款奔驰GLS450升级23P驾驶辅助 提升安全出行
辅助驾驶越来越多的被大家所青睐!为了提升驾驶安全性和舒适便捷性奔驰改装原厂半自动驾驶23P辅助系统 23P智能辅助驾驶系统还是很有必要的,因为在跑高速的时候可以使用23P智能驾驶的自动保持车速,保持车距,车道自动居中行驶以及自…...
iOS越狱检测总结
文章目录 前言检测越狱文件私有目录检测检测越狱软件检测系统目录是否变为链接动态库检测环境变量检测系统调用检测指令集调用检测其他方式检测 前言 在之前的文章中,已经带大家一起制作了一个屏蔽越狱检测的Tweak。本文就和大家一起学习整理一下iOS系统中有哪些越…...
场景驱动的 AI 体验设计:如何让智能 IDE 赋能遗留系统重写
作为 AutoDev 的核心开发,我们不仅在不断丰富 AutoDev 的功能以满足不同公司的定制需求,还在与各种团队进行持续交流。在处理遗留系统时,我们发现程序员们日常工作中需要面对大量使用过时技术、基础设施混乱的系统。 在这个背景下,…...
【封装UI组件库系列】搭建项目及准备工作
封装UI组件库系列第一篇搭建项目 前言 🌟搭建项目 创建工程 基本结构 1.创建8个组件展示页面 2.配置路由文件router/index.js 3.页面布局 🌟总结 前言 在前端开发中,大家可能已经用过各种各样的UI组件库了,现在市面上热…...
C#使用DateTime获取日期和时间
在C#中,DateTime类是用来处理日期和时间的类。它具有许多属性和方法,用于操作和获取日期和时间的不同部分。以下是DateTime类的一些常用属性和方法。 属性: 1、DateTime.Now:获取当前日期和时间。 DateTime currentDateTime D…...
rook-ceph部署
rook是云原生存储编排器,本身不提供存储。 下载 git clone --single-branch --branch v1.11.4 https://github.com/rook/rook.git cd rook/deploy/examples 修改镜像地址images.txt operator方式部署rook kubectl apply -f crds.yaml -f common.yaml -f operator…...
JVM基础- 垃圾回收器
基本介绍 Java虚拟机(JVM)中的垃圾回收器是用来自动管理内存的关键组件。它负责识别并回收不再使用的内存,从而防止内存泄漏。不同的JVM实现提供了多种垃圾回收器,每种回收器都有其特定的使用场景和性能特点。以下是一些常见的JV…...
数理统计的基本概念(二)
文章目录 抽样分布几个重要分布 Γ \Gamma Γ 分布 β \beta β 分布 χ 2 \chi^2 χ2 分布 t t t 分布 F F F 分布 分位数 参考文献 抽样分布 所谓抽样分布是指统计量的概率分布。确定统计量的分布是数理统计学的基本问题之一。 几个重要分布 Γ \Gamma Γ 分布 若随机变量 …...
CountDownLatch和CyclicBarrier
JUC(Java.util.concurrent)是Java 5中引入的一个并发编程库,它包含了许多用于多线程处理的工具类和接口。JUC主要提供了以下特性: 线程池:线程池可以提高线程的使用效率,避免频繁地创建和销毁线程ÿ…...
云原生正在重塑软件的整个生命周期(内附资料)
随着企业数字化转型进程的发展,企业面临着新旧商业形态的剧变,颠覆和重构时刻都在发生。 企业需要更加快速地感知用户侧的需求变化并做出调整,才有可能在竞争中持续积累优势。业务的个性化、敏捷化、智能化需求日益突显,数字化应…...
Node.js环境配置级安装vue-cli脚手架
一、下载安装Node.js (略) 二、验证node.js并配置 1、下载安装后,cmd面板输入node -v查询版本、npm -v ,查看npm是否安装成功(有版本号就行了) 2、选择npm镜像(npm config set registry https://registry.npm.taobao.org&…...
十七、Rust集成MQTT Client
1、信息整理 目前了解到的Rust MQTT项目有: bytebeamio/rumqtt 1.3k star、717 commits、Contributors 78、tokio、futures、tls、rumqttc(client):cargo add rumqttc https://github.com/bytebeamio/rumqtt/tree/main/rumqttc ru…...
HarmonyOS ArkTS开发语言介绍(三)
1 引言 Mozilla创造了JS,Microsoft创建了TS,Huawei进一步推出了ArkTS。 从最初的基础的逻辑交互能力,到具备类型系统的高效工程开发能力,再到融合声明式UI、多维状态管理等丰富的应用开发能力,共同组成了相关的演进脉…...
[架构之路-247]:目标系统 - 设计方法 - 软件工程 - 结构化方法的基本思想、本质、特点以及在软件开发、在生活中的应用
目录 前言: 一、什么是非结构化方法 1.1 什么是非结构化方法 1.2 非结构化方法的适用场合 二、什么是结构化方法 1.1 结构化方法诞生的背景:软件规模发展:大规模、复杂系统的需要 1.2 概述 1.3 主要特点与核心思想 三、结构化方法在…...
大模型的交互能力
摘要: 基础大模型显示出明显的潜力,可以改变AI系统的开发人员和用户体验:基础模型降低了原型设计和构建AI应用程序的难度阈值,因为它们在适应方面的样本效率,并提高了新用户交互的上限,因为它们的多模式和生…...
80%测试员被骗,关于jmeter 的一个弥天大谎!
jmeter是目前大家都喜欢用的一款性能测试工具,因为它小巧、简单易上手,所以很多人都愿意用它来做接口测试或者性能测试,因此,在目前企业中,使用各个jmeter的版本都有,其中以jmeter3.x、4.x的应该居多。 但是…...
为Claude Code配置Taotoken密钥与聚合端点实现编程辅助
为Claude Code配置Taotoken密钥与聚合端点实现编程辅助 Claude Code 是一款广受开发者欢迎的编程辅助工具,它能够提供代码补全、解释和调试建议。通过将其后端服务接入 Taotoken 平台,开发者可以利用平台聚合的多种大模型能力,在熟悉的编辑环…...
【RAG】【node_postprocessor04】ColPaliRerank 重排序示例分析
1. 案例目标本案例展示了如何使用ColPali重排序器来提高检索系统的相关性。ColPali是一种基于多模态嵌入的重排序技术,它能够更好地理解文档的语义内容,从而提供更准确的检索结果。主要目标包括:演示ColPali重排序器的基本使用方法对比直接检…...
怎么部署OpenClaw?2026年云端9分钟零门槛保姆级指南及百炼Coding Plan流程
怎么部署OpenClaw?2026年云端9分钟零门槛保姆级指南及百炼Coding Plan流程。OpenClaw作为阿里云生态下新一代的开源AI自动化代理平台,曾用名Moltbot/Clawdbot,凭借“自然语言交互自动化任务执行大模型智能决策”的核心能力,正在重…...
so-vits-svc 4.1终极实战指南:从零搭建专业歌声转换系统
so-vits-svc 4.1终极实战指南:从零搭建专业歌声转换系统 【免费下载链接】so-vits-svc SoftVC VITS Singing Voice Conversion 项目地址: https://gitcode.com/gh_mirrors/so/so-vits-svc 在人工智能语音合成领域,歌声转换技术正以前所未有的速度…...
Go语言构建轻量级反向代理Kraken:从核心原理到生产部署
1. 项目概述:一个轻量级、高性能的Web应用代理工具最近在折腾一些个人项目,经常需要在本地开发环境和远程服务器之间进行调试和测试。传统的方案要么太重,要么配置繁琐,要么性能堪忧。直到我发现了luisabwk/kraken这个项目&#x…...
ETA6911,12V/4A 独立开关模式锂离子电池充电器。
1.描述ETA6911是新一代高集成度同步开关模式充电器,内置同步场效应管,具备高开关频率与高充电效率特性。依托钰泰半导体专属电流检测技术,该芯片无需外置检测电阻,可实现最高4安培的充电电流输出。此外,其封装尺寸仅1.…...
【AISMM模型实战指南】:3大产品创新瓶颈的精准诊断与7天落地路径
更多请点击: https://intelliparadigm.com 第一章:AISMM模型与产品创新能力 核心构成与创新映射关系 AISMM(Artificial Intelligence Software Maturity Model)并非传统能力成熟度模型的简单延伸,而是将AI工程化实践…...
如何在Linux上快速解决RTL8821CU无线网卡驱动问题:完整指南
如何在Linux上快速解决RTL8821CU无线网卡驱动问题:完整指南 【免费下载链接】rtl8821CU Realtek RTL8811CU/RTL8821CU USB Wi-Fi adapter driver for Linux 项目地址: https://gitcode.com/gh_mirrors/rt/rtl8821CU 你刚在Linux系统上插入了RTL8821CU无线网卡…...
在自动化测试脚本中集成taotokenapi为硬件日志生成分析摘要
在自动化测试脚本中集成taotokenapi为硬件日志生成分析摘要 对于嵌入式硬件,尤其是STM32这类设备的测试,每天都会产生海量的日志文件。测试工程师需要从中筛选关键信息,定位潜在问题,这个过程耗时且容易遗漏。本文将介绍一种实践…...
B站字幕提取方法全攻略:从下载视频到一键导出字幕的完整实操
截至 2026 年,提取 B 站字幕的工具大致分为三类:在线网站工具、本地软件、以及微信小程序。其中微信小程序因为即用即走的便利性,用的人越来越多。我先给你拆解一个靠谱的微信小程序方案,然后再补充其他几条思路,你可以根据自己的使用频率来选。用提词匠直接处理 B 站字幕提取,…...
