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

这篇具有很好参考价值的文章主要介绍了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)
————————————————

​最后我们放松一下眼睛
unity C#深拷贝、浅拷贝、直接赋值区别与经典实例,unity,c#,java文章来源地址https://www.toymoban.com/news/detail-795340.html

到了这里,关于unity C#深拷贝、浅拷贝、直接赋值区别与经典实例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java基础:初始化ArrayList时直接赋值的四种方式

    在Java中,初始化ArrayList时直接赋值有以下几种常见方式: 构造器传入集合 : 或者在Java 9及以上版本中使用 List.of() 方法创建不可变列表: 使用匿名内部类 (不常用且可能引起混淆,实际编程中很少这样用): 注意:这种方式利用了匿名内部类的实例初始化块,但不是标准

    2024年04月22日
    浏览(28)
  • Java面试必备:深拷贝、浅拷贝、引用拷贝的区别

    Java中的拷贝可以分为深拷贝(Deep Copy)、浅拷贝(Shallow Copy)和引用拷贝(Reference Copy)。它们之间的区别如下: 浅拷贝: 只复制对象本身,而不复制对象包含的子对象。新旧对象之间共享子对象的引用,即新对象和原始对象中的子对象指向同一个内存地址。 浅拷贝:使用

    2023年04月11日
    浏览(22)
  • 【C#】【System.IO】关于拷贝文件夹以及(Directory和DirectoryInfo、File和FileInfo)的区别

    本次问题是想要拷贝文件夹,但是找了一圈发现只有File有Copy或者FileInfo的CopyTo,并没有Directory的拷贝操作方法。 针对C#中拷贝文件夹的方法就是先生成一个目标文件夹(destinationFolder)再将(soursefolder)中的文件依次拷贝到目标文件夹中,C#并没有提供封装好的方法将文件夹

    2024年02月08日
    浏览(28)
  • Unity 之 使用原生UGUI实现随手移动摇杆功能经典实例

    本文最终实现效果: 做一个实验看一下使用 ScrollRect 组件实现摇杆的原理。 在 Hierarchy 面板右键 UI - Scroll View 创建一个滚动视图,这个组件经常被应用于排行榜,选角色之类的可滑动的界面。 在 Scroll View - Viewport - Content 添加一个Image组件 运行场景,鼠标点击并拖动中间部分

    2024年01月17日
    浏览(33)
  • C++的引用 拷贝赋值和引用赋值

        💯 博客内容:C++的引用 拷贝赋值和引用赋值 😀 作  者:陈大大陈 🚀 个人简介:一个正在努力学技术的准前端,专注基础和实战分享 ,欢迎私信! 💖 欢迎大家:这里是CSDN,我总结知识和写笔记的地方,喜欢的话请三连,有问题请私信 😘 😘 😘 目录 引用  引用

    2024年02月12日
    浏览(28)
  • 前端面试题---深拷贝、浅拷贝的实现和解构赋值

    在 JavaScript 中实现深拷贝和浅拷贝可以采用不同的方法。下面分别介绍这两种拷贝方式的实现方式 1.浅拷贝(Shallow Copy) 浅拷贝(shallow copy)是一种复制对象或数组的操作,创建一个新的对象或数组,并将原始对象或数组的属性或元素的引用复制到新的对象或数组中。这意味

    2024年02月08日
    浏览(72)
  • 关于数据拷贝赋值方法

    提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 认知有限#x

    2024年02月13日
    浏览(63)
  • 【C++】vector类的模拟实现(增删查改,拷贝构造,赋值运算,深浅拷贝)

    🌏博客主页: 主页 🔖系列专栏: C++ ❤️感谢大家点赞👍收藏⭐评论✍️ 😍期待与大家一起进步! 我们模拟vector是用迭代器(start,end,endofstorage)来控制增删查改操作的 1普通构造 2迭代器构造 3初始化字符构造 4拷贝构造: 1当前大小(size()) 2总体容量(capacity()) 1begin()

    2024年02月15日
    浏览(45)
  • Unity中向量的点乘、叉乘区别和作用以及经典案例

    unity开发中我们要计算角度,判断位置,常用点乘、叉乘、归一化等等,我们看看他们的使用案例 点乘(Dot Product) 在Unity中的Vector3类提供了 Dot() 方法来计算两个向量的点乘。点乘的结果是一个标量值,可以用于判断两个向量的方向关系或者计算投影长度等。 叉乘(Cross P

    2024年04月28日
    浏览(29)
  • c++拷贝构造与赋值运算符重载

    目录 目录:         1:拷贝构造         2:赋值运算符重载                  前言:在上一章我们已经学习过了,构造与析构这两个默认成员函数了,接下来让我们一起来学习另外两个重要的默认成员函数。         首先让我们来讲一下默认成员函数这个概念,所谓

    2024年02月08日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包