C#浅拷贝与深拷贝详解:实例解析
199 浏览量
更新于2024-09-01
1
收藏 97KB PDF 举报
"C#浅拷贝和深拷贝实例解析"
在C#中,对象拷贝是一个关键的概念,尤其在处理复杂数据结构时。浅拷贝和深拷贝是两种不同的拷贝方式,它们的区别在于如何处理对象中的引用类型成员。
一、浅拷贝(Shallow Copy)
浅拷贝是指创建一个新对象,该对象拥有原始对象的所有字段的副本。对于值类型字段,浅拷贝会创建这些值的副本。然而,对于引用类型字段,浅拷贝只会复制引用,而不是引用的对象本身。这意味着原始对象和副本共享同一块内存空间,因此,如果其中一个对象修改了引用类型的字段,另一个对象也会受到影响。
以下是一个浅拷贝的例子:
```csharp
public class Cinema
{
public Room room;
public Film film;
// ...
public object Clone()
{
return MemberwiseClone(); // 对引用类型实施浅复制
}
}
public class Room
{
public int _maxSeat;
// ...
}
public struct Film
{
public string _name;
// ...
}
// 测试代码
Cinema cinema1 = new Cinema(room1, film1);
Cinema cinema2 = (Cinema)cinema1.Clone();
// 修改原始对象的引用类型成员
cinema1.room._maxSeat++;
// cinema1 和 cinema2 的引用类型成员 (_room) 都指向同一个 Room 实例
// 因此修改会同时影响两个对象
```
在这个例子中,`cinema2` 是 `cinema1` 的浅拷贝,它们的 `Film` 结构成员 `_film` 是独立的,因为 `Film` 是值类型。但 `Room` 类型是引用类型,所以 `cinema1` 和 `cinema2` 共享相同的 `Room` 实例。
二、深拷贝(Deep Copy)
深拷贝会创建一个全新的对象,不仅包含原始对象的值类型字段的副本,还包含所有引用类型字段的新副本,即新的对象实例。这样,即使修改了原始对象的引用类型成员,也不会影响到深拷贝的对象。
实现深拷贝的方法有多种,如使用序列化和反序列化、手动复制所有字段或者使用第三方库如AutoMapper。例如:
```csharp
public class Cinema
{
public Room room;
public Film film;
// ...
public Cinema DeepCopy()
{
return new Cinema { room = new Room(this.room._maxSeat), film = this.film };
}
}
// 测试代码
Cinema cinema1 = new Cinema(room1, film1);
Cinema cinema2 = cinema1.DeepCopy();
// 修改原始对象的引用类型成员
cinema1.room._maxSeat++;
// cinema1 和 cinema2 的 Room 字段现在是独立的
// 修改 cinema1 不会影响 cinema2
```
在这个例子中,`cinema2` 是 `cinema1` 的深拷贝,它有一个新的 `Room` 实例,因此修改 `cinema1` 的 `Room` 不会影响 `cinema2`。
总结:
- 浅拷贝只复制对象的表面,即值类型字段的副本和引用类型字段的引用,所有对象共享相同的数据。
- 深拷贝创建了一个全新对象,包括所有字段的副本,对于引用类型字段,也创建了新的实例。
- 选择浅拷贝还是深拷贝取决于你的需求:如果你不希望拷贝的对象受到原始对象的更改影响,应该使用深拷贝;反之,如果只需要简单的表层复制,浅拷贝即可满足需求。
2012-05-28 上传
2014-02-27 上传
2020-09-05 上传
点击了解资源详情
点击了解资源详情
点击了解资源详情
2016-10-19 上传
点击了解资源详情
点击了解资源详情
weixin_38532849
- 粉丝: 7
- 资源: 952
最新资源
- 正整数数组验证库:确保值符合正整数规则
- 系统移植工具集:镜像、工具链及其他必备软件包
- 掌握JavaScript加密技术:客户端加密核心要点
- AWS环境下Java应用的构建与优化指南
- Grav插件动态调整上传图像大小提高性能
- InversifyJS示例应用:演示OOP与依赖注入
- Laravel与Workerman构建PHP WebSocket即时通讯解决方案
- 前端开发利器:SPRjs快速粘合JavaScript文件脚本
- Windows平台RNNoise演示及编译方法说明
- GitHub Action实现站点自动化部署到网格环境
- Delphi实现磁盘容量检测与柱状图展示
- 亲测可用的简易微信抽奖小程序源码分享
- 如何利用JD抢单助手提升秒杀成功率
- 快速部署WordPress:使用Docker和generator-docker-wordpress
- 探索多功能计算器:日志记录与数据转换能力
- WearableSensing: 使用Java连接Zephyr Bioharness数据到服务器