C#中的深拷贝与浅拷贝的区别
C#中的深拷贝与浅拷贝的区别
C#中的深拷贝与浅拷贝的区别
1.基本的概念:
首先我们应该了解一下什么叫深拷贝与浅拷贝(Deep Copy and Shallow Copy)。
a.浅拷贝(Shallow Copy影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用。
b.深拷贝(Deep Copy 深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.完全产生新对象。
深拷贝与浅拷贝不同的是对于引用拷贝的处理,深拷贝将会在新对象中创建和原是对象中对应值类型的字段并且赋值。浅拷贝不会创建新引用类型,会返回相同的类 型引用。深拷贝会重新创建新对象,返回新对象的引用字。
2.深拷贝与浅拷贝实现机制:
从上面的概念我们了解了C#深拷贝与浅拷贝(Deep Copy and Shallow Copy)的不同之处。这个也就决定了两者有不同的实现方式。
对于值类型:
a.浅拷贝: 通过赋值等操作直接实现,将对象中的值类型的字段拷贝到新的对象中。
b.深拷贝:通过赋值等操作直接实现,将对象中的值类型的字段拷贝到新的对象中。 和浅拷贝相同
对于引用类型:
a.浅拷贝: MemberwiseClone 方法创建一个浅副本,方法是创建一个新对象,如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用原始对象,与原对象引用同一对象。
b.深拷贝:拷贝对象应用,也拷贝对象实际内容,也就是创建了一个新的改变新对象 不会影响到原始对象的内容
这种情况需要为其实现ICloneable接口中提供的Clone方法。
差别就是在对于引用类型的实现深拷贝和浅拷贝的时候的机制不同,前者是MemberwiseClone 方法实现,后者是通过继承实现ICloneable接口中提供的Clone方法,实现对象的深入拷贝。
3.代码实现
浅拷贝实例:
using System;
namespace Prototype_Shallow{
//因为我们在FCL里面已经有这样的接口所以我们就不定义新的Prototype了
public class ConcretePrototype1 : ICloneable{
private int m_ID;
public int ID{
get{
return this.m_ID;
}
}
public ConcretePrototype1(int id){
this.m_ID = id;
}
public object Clone(){
return this.MemberwiseClone();
}
}
public class ConcretePrototype2 : ICloneable{
private int m_ID;
public int ID
{
get
{
return this.m_ID;
}
}
public ConcretePrototype2(int id){
this.m_ID = id;
}
public object Clone(){
return this.MemberwiseClone();
}
}
}
代码说明:
我们具体的原型都继承了接口ICloneable,同时也实现了该接口里面唯一个一个方法Clone。我们可以在客户端这样创建对象ConcretePrototype1 p1 = new ConcretePrototype1(1);
ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
首先我们创建了对象p1,接下来我们用通过p1的科隆方法得到了对象c1,这就是一种浅拷贝(因为MemberwiseClone是浅拷贝)。
深拷贝实例:
namespace Prototype_Deep{
using System.Collections;
public class ConcretePrototype : ICloneable
{
private int m_ID;
public int ID
{
get
{
return this.m_ID;
}
}
private ArrayList m_arrayList = new ArrayList();
public ConcretePrototype(int id)
{
this.m_ID = id;
this.m_arrayList.Add("FirstObject");
this.m_arrayList.Add("SecondObject");
// ...
}
public object Clone()
{
ConcretePrototype c = new ConcretePrototype(this.ID);
c.m_arrayList = new ArrayList();
c.m_arrayList.Add("FirstObject");
c.m_arrayList.Add("SecondObject");
return c;
}
public ConcretePrototype DeepClone(){
return (ConcretePrototype)this.Clone();
}
}
}
代码说明:
该代码显示了如何实现深拷贝,深拷贝的原则就是对于那些引用的字段您需要new(new之前想想是不是能用前面学过的某个创建型的模式实现,这是一个好的习惯)一个出来,然后对该字段里面的对象一一拷贝,这样以来很容易出现循环拷贝,所以说深拷贝要比浅拷贝更难一些。
客户端可以通过
ConcretePrototype p = new ConcretePrototype(1);
ConcretePrototype c = p.DeepClone();
来实现克隆一个新的对象。
- C#中的readonly和const关键字
- C#插入排序
- C#中ToString()常见的格式
- C#操作datatable
- C#中BeginInvoke与EndInvoke
- C# string 和 stringbuilder 的区别
- C#选择排序
- C#中抽象类和接口的区别有哪些
- C# Task实现多线程
- C#中equals和==的区别有哪些
- C#栈和堆的区别
- c# 注册表操作
- C# #define条件编译
- C#enum枚举
- C#中TryParse的用法
- C#预处理器指令
- 《白狐的人生》热拍 贾征宇偶像包袱难自弃 图(白狐的人生热拍)
- 七夕取消了,牛郎织女没做核酸七夕已经取消(牛郎织女没做核酸七夕已经取消)
- 网友抵制 多地取消 夏日祭 为何惹众怒(网友抵制多地取消)
- 兄弟萌,今年的七夕又取消了 思考 思考(今年的七夕又取消了)
- 七夕取消是什么梗(七夕取消是什么梗)
- 这竟然是捏出来的 20种橡皮泥玩法让你轻松hold住魔娃(这竟然是捏出来的)
热门推荐
- mysql exists的用法(Mysql exists用法小结)
- centos安装php5.6(Centos7 Yum安装PHP7.2流程教程详解)
- python代码词频分析(python实现词法分析器)
- vue实现聊天(Vue+ssh框架实现在线聊天)
- dedecms增加导航内容(Dedecms搜索时 当然关键词和栏目名相同时 搜索结果为空的问题的解决方法)
- 网站数据服务器数据迁移(网站服务器迁移方案)
- javascript登录转注册界面(JavaScript实现登录窗体)
- python怎么去掉字符串的空格(Python切片操作去除字符串首尾的空格)
- dedecms怎么改使用页面(dedecms从子目录移动到根目录的方法)
- python的基础数据结构有哪些(详解python的四种内置数据结构)