【C#基础】浅拷贝&深拷贝
来源:互联网 发布:buildprop游戏优化代码 编辑:程序博客网 时间:2024/06/05 08:00
C#中的浅拷贝和深拷贝
[所谓拷贝,即通过某种方式获得已知C#对象的一个副本]问题一:什么是浅拷贝?
浅 -> 如果该对象中包含值类型和引用类型,那么拷贝后得到的新的对象值类型为原有对象中值类型的一个副本,该值存储在新的地址空间内;而新对象中的引用类型存储的地址仍指向原对象中引用类型所指向的对象的内存空间(即两个引用都指向同一块内存空间)
问题二:什么是深拷贝?
深 -> 与"浅"的不同之处在于拷贝得到的新对象中的引用类型所指向的对象虽然与原对象中引用类型所指向的对象具有相同的值,但是他们的内存空间是不同的(即新对象重新开辟了内存空间的来存储原对象中包含的引用类型对象)
问题三:如何实现浅拷贝?
浅拷贝的实现很简单,.NET Framework为我们提供了一个ICloneable接口,只要实现接口的Clone方法,并调用当前对象的MemberwiseClone()方法即可实现,当然你也可以在Clone对象中创建一个新的对象,并把this中的值一个个赋值给新的对象,此处引用类型也直接赋值即可。代码如下:
//实现ICloneable接口 class Person:ICloneable { public string Name{get;set;} public int Age{get;set;} //每个人都有一只猫 public Cat C{get;set;} public object Clone() { return this.MemberwiseClone(); } } class Cat { public string Name{get;set;} public override string ToString() { return "My cat's name is" + this.Name; } }测试代码:
static void Main(string[] args) { Person p = new Person() { Name = "Dream", Age = 18, C = new Cat() { Name="Catty"} }; Person pClone = p.Clone() as Person; Console.WriteLine(pClone.C); //浅拷贝:如果p.C发生改变,pClone.C也会发生同样的改变 p.C.Name = "Snoppy"; Console.WriteLine("改变p.C.Name后,pClone.C.Name的值:"); Console.WriteLine(pClone.C); Console.ReadLine(); }
问题四:如何实现深拷贝?
比较笨一点的方法就是如果拷贝的对象中仍包含引用对象,那么调用该引用对象的MemberwiseClone()即可,而值对象只需要简单的赋值即可,但是如果一个对象中包含了太多的引用对象,岂不是要对每一个对象都调用MemberwiseClone()方法么?所以:
建议使用对象的序列化进行深拷贝!!!代码如下(只需要改动浅拷贝中的Clone方法即可,测试代码与浅拷贝中的测试代码一致):
public object Clone() { //使用内存流来传递数据 using (Stream stream = new MemoryStream()) { IFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, this); stream.Seek(0, SeekOrigin.Begin); return formatter.Deserialize(stream) as Person; } }注意:如果一个对象需要被序列化,必须在类上面写明可被序列化的标记代码
建议:由于可以通过改写Clone方法来实现两种拷贝方式,为了区分拷贝的方式,只让Clone方法去实现一个浅拷贝,可以自己在类中定义深拷贝和浅拷贝的方法,并实现他们,在有需要的情况下。
- 【C#基础】浅拷贝&深拷贝
- C# 深拷贝/浅拷贝
- C# 深拷贝 浅拷贝
- C# 深拷贝浅拷贝
- c#深拷贝与浅拷贝
- 转载 C# 深拷贝与浅拷贝
- c#深拷贝与浅拷贝
- c#深拷贝与浅拷贝
- c#深拷贝与浅拷贝
- 浅析C#深拷贝与浅拷贝
- 浅析C#深拷贝与浅拷贝
- c#深拷贝与浅拷贝
- C# 浅拷贝与深拷贝区别
- 浅析C#深拷贝与浅拷贝
- C# 浅拷贝与深拷贝区别
- C#中浅拷贝与深拷贝
- c#深拷贝与浅拷贝
- C# 浅拷贝与深拷贝
- Linux下使用Eclipse编译C/C++代码时遇到问题的说明
- 求职之路
- SQL Server 2000 SP2 and below 不受该版本的 Windows 支持
- trunk、tunnel、lacp、聚合、级联的关系及区别
- sed命令详解
- 【C#基础】浅拷贝&深拷贝
- Fedroa1X以后版本开启用root用户登录的方法
- [MARK]行星采矿公司 DSI
- Android 亲测源码分享
- C语言设计模式:构造者模式
- 我喜欢陈欧的这段广告 你只闻到我的香水 却没看的我的汗水 你有你的规则 我有我的选择 你否定我的现在 我决定我的未来 你嘲笑我一无所有 不配去爱 我可怜你总是等待 你可以轻视我们的年轻 我们会
- Android NDK 入门小计
- windows下SAE应用部署
- C语言设计模式:装饰模式