C#浅复制和深复制
来源:互联网 发布:java crontrigger 编辑:程序博客网 时间:2024/05/22 00:34
在C#编程当中,经常需要克隆一个对象,这是不可避免的遇到一个问题就是浅复制和深复制的问题
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;using System.Runtime.Serialization.Formatters.Binary;namespace ClonePragram{ class Program { static void Main(string[] args) { MyClass myClass1 = new MyClass(10,"joy",10); /*1、myClass2和myClass1是同一个引用,指向同一个地址 * 结果:当myClass1属性改变,myClass2同样改变 */ MyClass myClass2 = myClass1; /*2、这里使用MemberwiseClone(),返回一个浅表副本,称“浅复制”MSDN上的解释:该方法是创建一个新对象, * 然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。 * 如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。 * 结果:myClass3复制了值类型myNum,但并没有复制引用的对象myNextClass, * 当myClass1中值类型属性myNum改变,而myClass3中myNum没有改变;myClass3和myClass1中 * 引用类型属性myNextClass还是同一个引用,myClass1中myNextClass改变,myClass3也改变 */ MyClass myClass3 = (MyClass)myClass1.Clone(); /*3、“深复制”,在Clone2()方法中,创建一个新对象MyNextClass,myClass4和myClass1中引用类型属性 * myNextClass不是同一个引用 */ MyClass myClass4 = (MyClass)myClass1.Clone2(); /*4、采用序列化和反序列化来“深复制”一个对象,首先将对象序列化到内存流中, * 此时对象和对象引用的所用对象的状态都被保存到内存中,然后将内存流中的状态信息反序列化到一个新的对象中。 */ MyClass myClass5 = (MyClass)myClass1.Clone3(); Console.WriteLine("改变数值之前"); Console.WriteLine(string.Format("myClass1: [myNum] = {0},[myNextNameProc] = {1},[myNextNumProc] = {2}", myClass1.myNum, myClass1.myNextClass.myNextNameProc, myClass1.myNextClass.myNextNumProc)); Console.WriteLine(string.Format("myClass2: [myNum] = {0},[myNextNameProc] = {1},[myNextNumProc] = {2}", myClass2.myNum, myClass2.myNextClass.myNextNameProc, myClass2.myNextClass.myNextNumProc)); Console.WriteLine(string.Format("myClass3: [myNum] = {0},[myNextNameProc] = {1},[myNextNumProc] = {2}", myClass3.myNum, myClass3.myNextClass.myNextNameProc, myClass3.myNextClass.myNextNumProc)); Console.WriteLine(string.Format("myClass4: [myNum] = {0},[myNextNameProc] = {1},[myNextNumProc] = {2}", myClass4.myNum, myClass4.myNextClass.myNextNameProc, myClass4.myNextClass.myNextNumProc)); Console.WriteLine(string.Format("myClass5: [myNum] = {0},[myNextNameProc] = {1},[myNextNumProc] = {2}", myClass5.myNum, myClass5.myNextClass.myNextNameProc, myClass5.myNextClass.myNextNumProc)); myClass1.myNum = 100; myClass1.myNextClass.myNextNameProc = "Tom"; myClass1.myNextClass.myNextNumProc = 100; Console.WriteLine("改变数值之后"); Console.WriteLine(string.Format("myClass1: [myNum] = {0},[myNextNameProc] = {1},[myNextNumProc] = {2}", myClass1.myNum, myClass1.myNextClass.myNextNameProc, myClass1.myNextClass.myNextNumProc)); Console.WriteLine(string.Format("myClass2: [myNum] = {0},[myNextNameProc] = {1},[myNextNumProc] = {2}", myClass2.myNum, myClass2.myNextClass.myNextNameProc, myClass2.myNextClass.myNextNumProc)); Console.WriteLine(string.Format("myClass3: [myNum] = {0},[myNextNameProc] = {1},[myNextNumProc] = {2}", myClass3.myNum, myClass3.myNextClass.myNextNameProc, myClass3.myNextClass.myNextNumProc)); Console.WriteLine(string.Format("myClass4: [myNum] = {0},[myNextNameProc] = {1},[myNextNumProc] = {2}", myClass4.myNum, myClass4.myNextClass.myNextNameProc, myClass4.myNextClass.myNextNumProc)); Console.WriteLine(string.Format("myClass5: [myNum] = {0},[myNextNameProc] = {1},[myNextNumProc] = {2}", myClass5.myNum, myClass5.myNextClass.myNextNameProc, myClass5.myNextClass.myNextNumProc)); Console.ReadKey(); } } //标记可序列化 [Serializable] public class MyClass : ICloneable { public int myNum; public MyNextClass myNextClass = new MyNextClass(); public MyClass(int num,string childName,int childNum) { myNum = num; myNextClass.myNextNameProc = childName; myNextClass.myNextNumProc = childNum; } //2 public object Clone() { return this.MemberwiseClone(); } //3 public object Clone2() { MyClass newMyClass = (MyClass)this.MemberwiseClone(); MyNextClass newChildClass = new MyNextClass(); newChildClass.myNextNameProc = this.myNextClass.myNextNameProc; newChildClass.myNextNumProc = this.myNextClass.myNextNumProc; newMyClass.myNextClass = newChildClass; return newMyClass; } //4 public object Clone3() { MemoryStream stream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, this); stream.Position = 0; return formatter.Deserialize(stream) as MyClass; } } [Serializable] public class MyNextClass { private string myNextName; public string myNextNameProc { get { return myNextName; } set { myNextName = value; } } public int myNextNumProc { get;set;} }}结果:
分析:Clone()是浅复制,Clone2()方法和Clone3()方法都是深复制,如果,对象中的引用属性太多,用Clone3()方法十分方便。
0 0
- C#浅复制和深复制
- C#中的深复制和浅复制
- C# 浅复制和深复制
- C#中List的浅复制和深复制
- c#浅度复制和深度复制
- 深复制和浅复制
- 深复制和浅复制
- 深复制和浅复制
- 深复制和浅复制
- 深复制和浅复制
- 深复制和浅复制
- 深复制和浅复制
- 深复制和浅复制
- 深复制和浅复制
- 浅复制和深复制
- 浅复制和深复制
- 深复制和浅复制
- 深复制和浅复制
- 申请IDP图文教程
- C/C++的一点技巧:如何在控制台工程中使用CString类
- 几款富文本web编辑器的用后感
- Linux内存参数参考-与oracle相关
- 查找相似项目
- C#浅复制和深复制
- ORACLE编码修改
- 情商低是硬伤
- HEVC/H.265与AVC/H.264对比总结
- 解决Window桌面上的图标都变成白底问题
- JVM性能优化, Part 2 ―― 编译器
- 使用 CDO 发送传递状态通知 For VBScript
- #pragma once
- Linux学习过程中的问题