unity C#深拷贝、浅拷贝、直接赋值区别与经典实例

文章目录

    • 浅拷贝
    • 深拷贝
    • 浅拷贝和直接赋值有啥区别

在C#中,浅拷贝(Shallow Copy)和深拷贝(Deep Copy)是两种不同级别的对象复制方式。它们的区别主要体现在处理引用类型字段时的行为。

浅拷贝

浅拷贝是指复制对象时,只复制对象本身所包含的值类型字段,并将引用类型字段简单地复制一份引用,而不是复制引用的对象内容。这意味着新旧对象中的引用类型字段指向相同的内存地址。因此,对任何一方引用类型的字段做出修改都会影响到另一个对象。

举例说明:

class Person
{public string Name { get; set; } // 值类型属性,字符串实际上是引用类型,但在此处作为不可变对象讨论public Car CarOwned { get; set; } // 引用类型属性
}class Car
{public string Brand { get; set; }
}// 创建原始对象
var originalPerson = new Person { Name = "Alice", CarOwned = new Car { Brand = "Toyota" } };
var shallowCopyPerson = originalPerson.MemberwiseClone(); // 使用默认的浅拷贝方法// 修改浅拷贝后的引用类型字段
shallowCopyPerson.CarOwned.Brand = "Ford";// 输出结果会显示两个对象的CarOwned.Brand都为"Frod"
Console.WriteLine(originalPerson.CarOwned.Brand); // 输出 "Ford"
Console.WriteLine(shallowCopyPerson.CarOwned.Brand); // 输出 "Ford"

在这个例子中,MemberwiseClone() 方法执行了浅拷贝操作,虽然 Person 对象被复制了一份,但 CarOwned 这个引用类型的字段并没有创建新的 Car 实例,而是共享了同一个实例。

深拷贝

深拷贝则不仅复制值类型字段,还复制引用类型字段所引用的对象,并为这些对象分配新的内存空间。这样一来,修改深拷贝后对象的引用类型字段不会影响到原对象。

深拷贝需要程序员自定义实现,通常涉及到递归遍历所有引用类型字段并逐一复制其内容。例如:

class Person
{public string Name { get; set; }public Car CarOwned { get; set; }// 自定义深拷贝方法public Person DeepCopy(){var copy = (Person)this.MemberwiseClone();if (this.CarOwned != null)copy.CarOwned = new Car { Brand = this.CarOwned.Brand }; // 深拷贝Car对象return copy;}
}class Car
{public string Brand { get; set; }
}// 创建原始对象
var originalPerson = new Person { Name = "Alice", CarOwned = new Car { Brand = "Toyota" } };
var deepCopyPerson = originalPerson.DeepCopy();// 修改深拷贝后的引用类型字段
deepCopyPerson.CarOwned.Brand = "Ford";// 输出结果会显示原对象的CarOwned.Brand仍然是"Toyota"
Console.WriteLine(originalPerson.CarOwned.Brand); // 输出 "Toyota"
Console.WriteLine(deepCopyPerson.CarOwned.Brand); // 输出 "Ford"

在上述深拷贝示例中,DeepCopy() 方法手动创建了 Car 类的新实例,这样 originalPersondeepCopyPerson 就拥有各自独立的 Car 对象,修改其中一个不会影响另一个。

浅拷贝和直接赋值有啥区别

浅拷贝(Shallow Copy)和直接赋值在处理引用类型变量时,其实是有相似之处的,但也有微妙的区别:

直接赋值:
当一个对象被直接赋值给另一个变量时,实际上创建的是原对象的一个引用副本。这意味着新变量和原变量都指向同一个内存地址,对于值类型而言,效果等同于复制了实际数据;而对于引用类型,只是复制了对原始对象的引用。

例如,在C#中:

class MyClass
{public string Value;
}MyClass obj1 = new MyClass { Value = "Hello" };
MyClass obj2 = obj1; // 直接赋值obj2.Value = "World"; // 改变 obj2 的 Value 属性

在此例中,obj2obj1 的引用副本,所以改变 obj2.Value 会导致 obj1.Value 同样变为 “World”,因为它们共享同一份引用类型的内部状态。

浅拷贝:
浅拷贝同样是创建了一个新的对象,并且复制了原对象的所有非引用类型字段值和引用类型的引用。与直接赋值类似,浅拷贝后的引用类型成员仍然指向原来的引用类型的实例。

例如,使用C#中的 MemberwiseClone() 方法进行浅拷贝:

class MyClass
{public string Value;public AnotherClass ReferenceTypeField;public MyClass ShallowCopy(){return (MyClass)this.MemberwiseClone();}
}class AnotherClass { /* ... */ }MyClass obj1 = new MyClass { Value = "Hello", ReferenceTypeField = new AnotherClass() };
MyClass obj3 = obj1.ShallowCopy(); // 浅拷贝obj3.Value = "World"; // 改变 obj3 的 Value 属性
obj3.ReferenceTypeField.SomeProperty = "New Value"; // 改变引用类型字段属性// 这里,obj1.Value 不受影响,但 obj1.ReferenceTypeField.SomeProperty 会被修改

在这个例子中,虽然 obj3obj1 的浅拷贝,改变了 obj3.Value 并不影响 obj1.Value,因为这里 Value 是值类型(字符串在.NET中是不可变类型)。然而,ReferenceTypeFieldobj1obj3 中指向的是同一个 AnotherClass 实例,因此更改 obj3.ReferenceTypeField 的属性会影响到 obj1.ReferenceTypeField

总结:

  • 直接赋值:简单地将源对象的引用传递给目标变量,两者指向相同的内存地址。
  • 浅拷贝:创建了一个新对象,其值类型字段拥有独立的副本,而引用类型字段依然指向原有对象的引用,即不创建引用类型内部状态的新副本。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

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

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

相关文章

【金猿人物展】DataPipelineCEO陈诚:赋能数据应用,发挥未来生产力

‍ 陈诚 本文由DataPipelineCEO陈诚撰写并投递参与“数据猿年度金猿策划活动——2023大数据产业年度趋势人物榜单及奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 我们处在一个“见证奇迹”的时代。在过去的20年间,我们见证了大数据技术快速发展所带…

VScode全局搜索屏蔽、显示屏蔽指定文件类型及文件夹

1.键盘上按快捷键“ crtl 逗号 ”启动设置界面 crtl ,设置界面显示如下: 2.搜索屏蔽 2.1.输入 search.exclude search.exclude 设置界面显示如下: 2.2. 点击下图红色箭头“Add Pattern”,添加想要屏蔽的文件类型或文件夹 **/*.git *…

做网页抓取时如何处理验证码

网络爬虫是自动从网站提取数据的过程,它已经彻底改变了企业获取信息和获取洞察的方式。然而,为了防止自动化机器人访问网站,CAPTCHA旨在阻碍网络爬虫的工作。在本文中,我们将探讨处理CAPTCHA的有效策略,并介绍Capsolve…

详解Skywalking 服务Overview页面的参数含义(适合小白)

本文针对刚刚接触skywalking的同学,重点讲解服务Overview页面中各个参数的含义,为大家快速上手skywalking会起到帮助作用! 最重要的三个指标 Service Apdex(数字):当前服务的评分 Successful Rate(数字&a…

0104 AJAX介绍

Ajax 的全称是 Asynchronous Javascript And XML (异步 JavaScript 和 XML )。 通俗的理解:在网页中利用 XMLHttpRequest 对象和服务器进行数据交互的方式,就是 Ajax Ajax 能让我们轻松实现网页与服务器之间的数据交互。 浏览器…

【ceph】在虚拟环境中需要给osd所在的虚拟盘扩容操作

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》:python零基础入门学习 《python运维脚本》: python运维脚本实践 《shell》:shell学习 《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战 《k8…

国内开源环境漫谈

我国开源软件产业相较于欧美发达国家而言起步相对较晚,开源项目很少超过五年,开发者较年轻。国外很多开源项目都是10年以上的规划与投入。在开源社区发展初期、发展期、协作期、结晶期与流行期的五个阶段中,中国的开源社区平台大多处于前三个…

IDEA新建SpringBoot工程时java版本只有17和21

解决方法:替换源 参考博客:https://www.kuazhi.com/post/712799571.html

数据仓库研发规范

数据仓库研发规范 本文将介绍数据仓库研发规范的阶段规划、角色职责和整体流程。 在大数据时代,规范地进行数据资产管理已成为推动互联网、大数据、人工智能和实体经济深度融合的必要条件。贴近业务属性、兼顾研发各阶段要点的研发规范,可以切实提高研…

c++算法之二分

目录 二分法简介 解题步骤 整数二分 模板 例题 输入描述 输出描述 样例输入输出 解 浮点二分 模板 二分答案(最重要) 模板 例题 跳石头 题目描述 输入描述 输出描述 输入输出样例 解 例题 肖恩的苹果林 输入描述 输出描述 解 测…

android 13.0 Launcher3长按app弹窗设置为圆角背景功能实现二

1.前言 在13.0的系统ROM定制化开发中,在进行一些Launcher3的定制化开发中,在使用app的弹窗的功能时,会弹出应用信息和 微件之类的内容,所以在定制需求中,需要默认设置为圆角背景,接下来就来分析下相关功能的实现如图: 2.Launcher3长按app弹窗设置为圆角背景功能实现二的…

基于JAVA的固始鹅块销售系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 鹅块类型模块2.3 固始鹅块模块2.4 鹅块订单模块2.5 评论管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 鹅块类型表3.2.2 鹅块表3.2.3 鹅块订单表3.2.4 鹅块评论表 四、系统展示五、核心代码5.…

每日一练:LeeCode-104. 二叉树的最大深度【二叉树】

本文是力扣LeeCode-104. 二叉树的最大深度 学习与理解过程,本文仅做学习之用,对本题感兴趣的小伙伴可以出门左拐LeeCode。 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例…

WAMP apache 无法启动(端口 80 未使用)

这段时间系统重装后,安装WAMP Server,装好后点击启动绿了下然后又变成了黄色,托盘图标无论是左键点击还是右键点击都没有反应,wampapache64服务也启动不起来,提示“windows不能在本地计算机启动wampapache”&#xff0…

【npm link】Node命令中的npm link命令的使用,还有CLI全局命令的使用,开发命令行工具必不可少的部分

😁 作者简介:一名大四的学生,致力学习前端开发技术 ⭐️个人主页:夜宵饽饽的主页 ❔ 系列专栏:NodeJs 👐学习格言:成功不是终点,失败也并非末日,最重要的是继续前进的勇气…

Mysql查询与更新语句的执行

一条SQL查询语句的执行顺序 FROM&#xff1a;对 FROM 子句中的左表<left_table>和右表<right_table>执行笛卡儿积&#xff08;Cartesianproduct&#xff09;&#xff0c;产生虚拟表 VT1 ON&#xff1a;对虚拟表 VT1 应用 ON 筛选&#xff0c;只有那些符合<join_…

yapi无法注册解决,使用yapi pro即可注册,接口文档生成,java,json

1.气屎我了&#xff0c;直接用yapi pro就可以用&#xff0c;害的我弄了半天 2.地址&#xff1a;https://yapi.pro/login 3.yapi pro比较卡顿。开启无痕模式轻松解决该问题&#xff08;手动狗头&#xff09;祝你开启新大陆 yapi pro yapi

ChatGPT能帮助我们人类做什么

一、ChatGPT可以在多个方面帮助人类&#xff1a; 回答问题&#xff1a; ChatGPT可以回答各种问题&#xff0c;提供信息和解释概念。 创造性写作&#xff1a; 它可以生成文章、故事、诗歌等创意性文本。 学术辅助&#xff1a; ChatGPT可以辅助学术研究&#xff0c;提供解释、背…

DNS解析和主从复制

一、DNS名称解析协议 二、DNS正向解析 三、DNS主从复制 主服务器 从服务器

安装rlwrap库出现问题

背景&#xff1a;oracle的sqlplus还是那么难用&#xff0c;不知道为什么不打包解决这个问题&#xff0c;留给用户&#xff0c;内核硬&#xff0c;就是猖狂。废话不多说。下载解压rlwrap-0.46.1.tar.gz;进入/tmp/database/rlwrap-0.46.1源码包&#xff0c;./configure checki…