.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只复制对象,并返回对副本的一个引用。
  • 浅拷贝是复制了类中所有值类型,若类包含引用类型的字段或属性,就只复制引用,而不复制引用的对象。
  • 深拷贝除了复制类中值类型,还会对引用类型做特殊处理,对其引用的对象创建副本并赋予原对象中相同的值。

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

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

相关文章

艺术作品3D虚拟云展厅能让客户远程身临其境地欣赏美

艺术品由于货物昂贵、易碎且保存难度大,因此在艺术品售卖中极易受时空限制,艺术品三维云展平台在线制作是基于web端将艺术品的图文、模型及视频等资料进行上传搭配,构建一个线上艺术品3D虚拟展厅,为艺术家和观众提供了全新的展示和…

opencv-python 印刷质量缺陷的视觉检测

Windows10PythonYolov8ONNX图片缺陷识别,并在原图中标记缺陷,有onnx模型则无需配置,无需训练。 ** PythonYolov8ONNX实时缺陷目标检测原文 labelimg使用指南 windows使用YOLOv8训练自己的模型(0基础保姆级教学) pyth…

Chrome和chromedriver版本不匹配导致的UI自动化测试无法运行的问题

今天,遇到一个小问题,本来跑的好好UI自动化测试脚本突然不好使了,期初怀疑是页面元素有调整导致脚本出现异常无法正常执行,经排查后发现近期页面没有任何调整。 这下头大了,啥也没改,怎么好好的脚本不能跑…

Vue3鼠标拖拽生成区域块并选中元素

Vue3鼠标拖拽生成区域块并选中元素&#xff0c;选中的元素则背景高亮(或者其它逻辑)。 <script setup> import { ref } from vue// 区域ref const regionRef ref(null)// 内容ref const itemRefs ref(null)// 是否开启绘画区域 const enable ref(false)// 鼠标开始位置…

vite打包vue2 history路由模式的的项目部署线上后<router-view />页面显示空白,命令行也不报错,本地是没有问题的

如题&#xff0c;本地畅通无阻&#xff0c;但是部署到服务器上就无法访问&#xff0c;本地是localhost://login可以访问到&#xff0c;但是因为我这里所有前端项目有一个路由映射&#xff0c;相当于是一个二级路由&#xff0c;导致线上路由出错&#xff0c;所以给路由加一个bas…

LVS+keepalived——高可用集群

lvskeepalived&#xff1a;高可用集群 keepalived为lvs应运而生的高可用服务。lvs的调度器无法做高可用&#xff0c;于是keepalived这个软件。实现的是调度器的高可用。但是&#xff1a;keepalived不是专门为lvs集群服务的&#xff0c;也可以做其他代理服务器的高可用。 lvs的…

基于SSM的进销存管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Vue typescript项目配置eslint+prettier

1.安装依赖 安装 eslint yarn add eslint --dev安装 eslint-plugin-vue yarn add eslint-plugin-vue --dev主要用于检查 Vue 文件语法 安装 prettier 及相关插件 yarn add prettier eslint-config-prettier eslint-plugin-prettier --dev安装 typescript 解析器、规则补充 …

Spring-IOC-@Import的用法

1、Car.java package com.atguigu.ioc; import lombok.Data; Data public class Car {private String cname; }2、 MySpringConfiguration2.java package com.atguigu.ioc; import org.springframework.context.annotation.Bean; import org.springframework.context.annotatio…

树莓派的的串口通信协议

首先&#xff0c;回顾一下串口的核心知识点&#xff0c;也是面试重点&#xff1a; 串口通信通常使用在多机通讯中串口通信是全双工的决定串口通信的成功与否的是 数据格式 和 波特率数据格式&#xff1a;1. 数据位 2.停止位 3. 奇偶校验位 树莓派恢复串口 回忆前几节树莓派刷机…

Vue3 配置全局 scss 变量

variables.scss $color: #0c8ce9;vite.config.ts // 全局css变量css: {preprocessorOptions: {scss: {additionalData: import "/styles/variables.scss";,},},},.vue 文件使用

AI大发展:人机交互、智能生活全解析

目录 ​编辑 人工智能对我们的生活影响有多大 人工智能的应用领域 一、机器学习与深度学习 二、计算机视觉 三、自然语言处理 四、机器人技术 五、智能推荐系统 六、智能城市和智能家居 ​编辑 自己对人工智能的应用 自己的人工智能看法&#xff1a;以ChatGPT为例 …

watcheffect的用法

需求&#xff1a;监听用户给金额字段改大了还是改小了 let previousAmount: number | null null; watchEffect(() > {for (let i 0; i < projectList.value.length; i) {const currentAmount Number(projectList.value[i].je);if (previousAmount ! null) { //不是空…

一种全新且灵活的 Prompt 对齐优化技术

并非所有人都熟知如何与 LLM 进行高效交流。 一种方案是&#xff0c;人向模型对齐。 于是有了 「Prompt工程师」这一岗位&#xff0c;专门撰写适配 LLM 的 Prompt&#xff0c;从而让模型能够更好地生成内容。 而另一种更为有效的方案则是&#xff0c;让模型向人对齐。 这也是…

BE节点经常挂掉:[IO_ERROR]failed to list /proc/27349/fd/: No such file or directory

最近BE节点经常挂掉 Caused by: java.lang.RuntimeException: Failed to execute internal SQL. org.apache.doris.common.UserException: errCode 2, detailMessage There is no scanNode Backend available.[10031: not alive] OriginStatement{originStmtSELECT * FROM _…

分布式任务调度-XXL-job

目录 源码仓库地址 前置环境 docker容器环境配置 连接linux数据库&#xff0c;并创建任务调度所用到的数据库xxl-job。 用到的表sql 打开映射网址 后端配置使用任务调度 依赖 yml配置 使用架构 config配置 job使用 快速入门使用 任务调度执行器 任务调度执行管理​编…

ck 配置 clickhouse-jdbc-bridge

背景 ck可以用过clickhouse-jdbc-bridge技术来直接访问各数据库 安装配置 需要准备的文件 clickhouse-jdbc-bridge https://github.com/ClickHouse/clickhouse-jdbc-bridge 理论上需要下载源码然后用mavne打包&#xff0c;但提供了打包好的&#xff0c;可以推测用的是mave…

USART的标准库编程

使用USART与计算机通信 电脑上只有usb端口 没有TX 和RX需要一个USB转TTL电平模块来实现通信 芯片C8T6中只有三个UASRT 选其中一个UASRT来通信即可 那么如何定位那个USART的TX 和RX引脚呢&#xff1f; 方式1 查找最小系统板引脚分布图 查找USART1的引脚 RTS CTS是硬件流控 CK…

iOS 17.0 YYText 崩溃处理

YYText&#xff0c;发现在iOS 17上运行会崩溃&#xff0c;触发了系统的断言&#xff1a; UIGraphicsBeginImageContext() failed to allocate CGBitampContext: size{382, 0}, scale3.000000, bitmapInfo0x2002. Use UIGraphicsImageRenderer to avoid this assert. 查了下 ap…

C练习题_15

一、单项选择题(本大题共20小题&#xff0c;每小题2分&#xff0c;共40分。在每小题给出的四个备选项中&#xff0c;选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上。) 在下列说法中&#xff0c;&#xff08;&#xff09;是正确的。 A.C程序从第一个函数开始…