.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.rhkb.cn/news/205383.html

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

相关文章

Umi-OCR图片批量识别文字工具

OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/粘贴/批量导入图片,段落排版/排除水印,扫描/生成二维码。内置多国语言库。 项目地址:https://github.com/hiroi-sora/Umi-OCR

F. Magic Will Save the World

首先积攒了能量打了怪再积攒是没有意义的,可以直接积攒好,然后一次性进行攻击 那么怎么进行攻击了?可以尽量的多选怪物使用水魔法攻击剩余的再用火魔法进行攻击, 也就是只要存在合法的体积(即装入背包的怪物的体积之…

封装一些可能会用到的JS的Dom操作方法(非JS自带的方法)

1. 父元素节点下的子元素节点逆序 HTMLElement.prototype.childRevers function () {var all_num this.childElementCount;if (all_num) {while(all_num--){this.appendChild(this.children[all_num]);}} } // 获取 ul 父节点对象 var oul document.getElementsByTagName(u…

Python web自动化测试 —— 文件上传

​文件上传三种方式: (一)查看元素标签,如果是input,则可以参照文本框输入的形式进行文件上传 方法:和用户输入是一样的,使用send_keys 步骤:1、找到定位元素,2&#…

在很多nlp数据集上超越tinybert 的新架构nlp神经网络模型

在很多nlp数据集上超越tinybert 的新架构nlp神经网络模型 网络结构图测试代码网络结构图 测试代码 import paddle import numpy as np import pandas as pd from tqdm import tqdmclass FeedFroward(paddle.nn.Layer):

图面试专题

一、概念 和二叉树的区别:图可能有环 常见概念 顶点(Vertex): 图中的节点或点。边(Edge): 顶点之间的连接线,描述节点之间的关系。有向图(Directed Graph)&…

基于BP神经网络的手写体数字识别matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 filename dir(images\*.bmp); %图像文件格式 load BP.matfilename dir(test\*.bmp); …

[BJDCTF2020]The mystery of ip1

提示 ssti模板注入head头x-forwarded-for 每一次做题的最开始流程都大致因该是 信息收集找可以操控的地方 查看hint页面的源代码又发现它提示说 ####你知道为什么会知道你的ip吗 查看flag页面 从刚才给我的提示以及他这里显示的我的ip,大概找到了我可操作的可控点 …

【Java SE】带你在String类世界中遨游!!!

🌹🌹🌹我的主页🌹🌹🌹 🌹🌹🌹【Java SE 专栏】🌹🌹🌹 🌹🌹🌹上一篇文章:带你走近Java的…

ubuntu22.04系统下载程序和依赖,并拷贝到指定路径下

脚本1 apt install aptitude apt-get -d install xxx #xxx是待下载的安装包 mv /var/cache/apt/archives/* /home/tuners/1apt install aptitude apt-get -d install xxx mv /var/cache/apt/archives/*.deb /home/tuners/1 xxx 为程序包名称 /home/tuners/1为保存程序包的…

PM2 在线和离线部署uvicorn和fastapi项目过程

PM2介绍 PM2 is a daemon process manager that will help you manage and keep your application online 24/7 PM2是一个后台进程管理工具,能帮助管理应用和维持应用7*24小时运行。 PM2在线安装 npm install pm2 -gPM2离线安装(适用于内网) 参见 如何离线安装pm2…

git-4

1.在GitHub上创建个人仓库 现在仓库中有LICENSE文件,但本地没有这个文件,该怎么办呢?往下看 2.把本地仓库同步到GitHub 3.不同人修改了不同文件如何处理? 两个人在同一个分支上,两个人修改了不同文件 其中一人&…

案例研究|北京交通大学基于DataEase开展多场景校园数据分析与展示

北京交通大学是教育部直属,教育部、交通运输部、北京市人民政府和中国国家铁路集团有限公司共建的全国重点大学,是国家“211工程”“985工程优势学科创新平台”“双一流”建设高校。 多年来,北京交通大学积极发挥信息技术赋能学校人才培养、…

基于springboot实现乒乓球预约管理系统项目【项目源码】

基于springboot实现乒乓球预约管理系统演示 系统的开发环境 浏览器:IE 8.1(推荐6.0以上) 开发使用语言:JAVA JDK版本:JDK_8 数据库管理系统软件:Mysql 运行平台:Windows 7 运行环境&#…

【hacker送书第6期】深入理解Java核心技术

第6期图书推荐 内容简介作者简介精彩书评参与方式 内容简介 《深入理解Java核心技术:写给Java工程师的干货笔记(基础篇)》是《Java工程师成神之路》系列的第一本,主要聚焦于Java开发者必备的Java核心基础知识。全书共23章&#xf…

关于鸿蒙网络请求的问题

https://developer.huawei.com/consumer/cn/forum/topic/0204136145853212268?fid0102683795438680754 鸿蒙OS 代码 import http from ohos.net.http;export const httpUtils (url: string, data: any) > {return new Promise((resolve, reject) > {let httpRequest …

鸿蒙开发已成新趋势

随着华为鸿蒙操作系统的快速崭露头角,鸿蒙开发已然成为当前技术领域的热门新趋势。本文将深入探讨鸿蒙开发的重要性和独特优势,并详细介绍一些关键的鸿蒙开发技术和工具,以及它们对开发者个人和整个行业带来的深远影响。 首先,鸿蒙…

【Apifox】测试工具自动编写接口文档

在开发过程中,我们总是避免不了进行接口的测试, 而相比手动敲测试代码,使用测试工具进行测试更为便捷,高效 今天发现了一个非常好用的接口测试工具Apifox 相比于Postman,他还拥有一个非常nb的功能, 在接…

Table和HashBasedTable的使用案例

------------------- 1.普通使用 package org.example.testhashbasedtable;import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table;import java.util.Map;public class TestHashBasedTable {public static void main(String[] args) {Ta…

福州大学《嵌入式系统综合设计》 实验八:FFMPEG视频编码

一、实验目的 掌握使用算能平台进行视频编码的流程,包括开发主机环境与云平台的配置,视频编码程序的编写与理解,代码的编译、运行以及学习使用码流分析工具分析视频压缩码流等。 二、实验内容 搭建实验开发环境,编译并运行编码…