回顾002--C# 中 赋值 VS浅拷贝 VS 深拷贝
一:通俗解释:
赋值:---如果是值类型或者string,赋值的实例;如果是引用类型,赋值的是引用地址
浅拷贝----仅仅复制了引用地址,复制对象或被复制对象的改变,是互相影响的(一变则都变)
深拷贝---对对象的完全复制,即:复制对象或被复制对象的改变,相互不影响(相互独立,互不影响)
二:实例说明:
值类型的复制都是深拷贝;
引用类型的复制(没有特殊处理过)都是浅复制(除string类型)
对于类型来说存在这样一个有趣现象:(代码见附件:Employee类中有属性:Department(Department类型),Emp_Name(string类型),Emp_Age(int类型))
假设:存在Employee对象emp;
创建新对象 |
Employee empCopy= emp; |
Employee empShalllowCopy= |
Employee empDeepCopy= |
结果描述 |
当emp的属性变化时,empCopy对象的属性跟着变化 |
当emp属性变化时,empShalllowCopy对象中只有Department属性跟随emp的变化而变化 |
当emp属性变化时,empDeepCopy对象中的属性不变化。二者的变化不会相互影响。 |
主要代码展示:
Console.WriteLine("==============using self-define method: DeepClone && ShalllowClone"); Employee emp1 = new Employee() { EmpName = "tom1", Age = 26, Department = new Department() { Dep_Id = 1, Dep_Name = "开发部门" } }; Console.WriteLine("==============start Copy");// 完全相互影响 Employee emp1CopyClone = emp1; emp1.EmpName = "jerryCopy"; emp1.Age = 18; emp1.Department.Dep_Name = "测试部门Copy"; Console.WriteLine(emp1CopyClone.EmpName + " " + emp1CopyClone.Age + " " + emp1CopyClone.Department.Dep_Name); Console.WriteLine("==============start ShalllowClone"); //部分相互影响 Employee emp1ShalllowClone = emp1.ShalllowClone(); emp1.EmpName = "jerry1"; emp1.Age = 28; emp1.Department.Dep_Name = "测试部门"; Console.WriteLine(emp1ShalllowClone.EmpName + " " + emp1ShalllowClone.Age + " " + emp1ShalllowClone.Department.Dep_Name); Console.WriteLine("==============start DeepClone"); //完全独立 Employee emp1ShalllowClone1 = emp1.DeepClone(); emp1.EmpName = "jerry1111"; emp1.Age = 2811; emp1.Department.Dep_Name = "测试部门111"; Console.WriteLine(emp1ShalllowClone1.EmpName + " " + emp1ShalllowClone1.Age + " " + emp1ShalllowClone1.Department.Dep_Name);
类被克隆(深拷贝、浅拷贝),微软都建议类需继承ICloneable接口,用以明确告诉调用者该类可被拷贝:
[Serializable] public class Employee : ICloneable { public string EmpName { get; set; } public int Age { get; set; } public Department Department { get; set; } #region 默认实现接口 , 返回值类型为浅拷贝对象(仅对引用类型来说)---- public object Clone() { return this.MemberwiseClone(); } #endregion #region 自定义 深拷贝 和 浅拷贝 方法 //浅拷贝 public Employee ShalllowClone() { return Clone() as Employee; } //深拷贝 public Employee DeepClone() { using (Stream objectStream = new MemoryStream()) { IFormatter formatter = new BinaryFormatter(); formatter.Serialize(objectStream, this); objectStream.Seek(0, SeekOrigin.Begin); return formatter.Deserialize(objectStream) as Employee; } } #endregion }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通