- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章浅谈.net平台下深拷贝和浅拷贝由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
基本概念:
浅拷贝:指对象的字段被拷贝,而字段引用的对象不会被拷贝,拷贝对象和原对象仅仅是引用名称有所不同,但是它们共用一份实体。对任何一个对象的改变,都会影响到另外一个对象。大部分的引用类型,实现的都是浅拷贝,引用类型对象之间的赋值,就是复制一个对象引用地址的副本,而指向的对象实例仍然是同一个.
深拷贝:指对象的子段被拷贝,同时字段引用的对象也进行了拷贝。深拷贝创建的是整个源对象的结构,拷贝对象和原对象相互独立,不共享任何实例数据,修改一个对象不会影响到另一个对象。值类型之间的赋值操作,执行的就是深拷贝.
基本概念之参考代码:
class Program { static void Main(string[] args) { Student s1 = new Student("li", 23),
。
//浅拷贝 Student s2 = s1; s2.Age = 27; s1.ShowInfo();//li's age is 27 。
//深拷贝 int i = 12; int j = i; j = 22; Console.WriteLine(i);//12 。
Console.Read(); } } 。
class Student { public string Name; public int Age,
public Student(string name, int age) { Name = name; Age = age; } 。
public void ShowInfo() { Console.WriteLine("{0}'s age is {1}", Name, Age); } } 。
分析:
。
在上例中,实例s2对s1进行了浅拷贝,对s2中的Age字段进行更改,继而影响实例s1中的Age字段.
深拷贝中,仅仅是值类型间简单的赋值,对“j”做出的更改不会更改“i”的值.
深浅拷贝的实现:
。
。
MemberwiseClone:创建一个浅表副本。过程是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用对象.
参考代码:
class Program { static void Main(string[] args) { ClassA ca = new ClassA(); ca.value = 88; ClassA ca2 = new ClassA(); ca2 = (ClassA)ca.Clone(); ca2.value = 99; Console.WriteLine(ca.value + "-----" + ca2.value);//88---99 。
。
ClassB cb = new ClassB(); cb.Member.value = 13,
ClassB cb2 = (ClassB)cb.Clone(); cb2.Member.value = 7; Console.WriteLine(cb.Member.value.ToString() + "------" + cb2.Member.value.ToString());//浅拷贝:7---7 深拷贝:13----7 。
Console.Read(); } } 。
public class ClassA : ICloneable { public int value = 0,
public object Clone() { return this.MemberwiseClone(); } } 。
public class ClassB : ICloneable { public ClassA Member = new ClassA(),
public object Clone() { //浅拷贝 return this.MemberwiseClone(),
//深拷贝 ClassB obj = new ClassB(); obj.Member = (ClassA)Member.Clone(); return obj; } } 。
。
分析:
上例中,ca2复制ca对象,实现了深度拷贝。结果如同代码中显示:ca2中值类型字段的改变并不影响ca中的字段.
在类ClassB中,引用类型成员Member,如果用ClassA中的clone方法实现则仅仅实现的是浅拷贝,在上述参考代码中能够看出:对cb2的member的改变影响着cb。但是当使用参考代码中的深度拷贝后,对cb2的member的改变则不会影响着cb.
在网上找到一个综合的例子,有对比的来进行解释深浅拷贝:
实例1:
。
public class Sex:ICloneable { private string _PSex; public string PSex { set{ _PSex = value;} get { return _PSex; } } 。
。
//public object Clone() //{ // return this.MemberwiseClone(); //} } 。
public class Person : ICloneable { 。
private Sex sex = new Sex(); public int aa = 3,
public string pSex { set { sex.PSex = value; } get { return sex.PSex; } } private string _PName; public string PName { set { this._PName = value; } get { return this._PName; } } 。
public void ShowPersonInfo() { Console.WriteLine("-------------------------"); Console.WriteLine("Name:{0} Sex:{1}", _PName, this.pSex); Console.WriteLine("-------------------------"); Console.WriteLine(this.aa); } //浅拷贝 public object Clone() { return this.MemberwiseClone(); } //深拷贝 public object DeepClone() { Person newP = new Person(); newP.PName = this._PName; newP.pSex = this.pSex; return newP; } } 。
class Program { static void Main(string[] args) { Console.WriteLine("原对象:"); Person p = new Person(); p.PName = "Lee"; p.pSex = "男",
p.ShowPersonInfo();//原对象:lee 男 3 。
//浅拷贝 Person copy = (Person)p.Clone(); //深拷贝 Person dcopy = (Person)p.DeepClone(),
Console.WriteLine("修改后的原对象:"); p.PName = "Zhao"; p.pSex = "女"; p.aa = 1; p.ShowPersonInfo();//zhao 女 1 。
Console.WriteLine("修改后的浅拷贝对象:"); copy.ShowPersonInfo();//lee 女 3 。
Console.WriteLine("修改后的深拷贝对象:"); dcopy.ShowPersonInfo();//lee 男 3 。
Console.WriteLine("直接拷贝对象:"); Person PP = p; PP.ShowPersonInfo();//zhao 女 1 。
Console.ReadLine(); } } 。
。
分析:
首先需指出,上例中在类Sex中,加入Clone方法和不加对实例中运算结果没有影响.
类Person中,引用类型但却是string类型的PName字段,引用类型pSex字段,值类型aa.
初始值:lee 男 3 (先进行深浅拷贝) 。
修改值:zhao 女 1 。
浅拷贝值:lee 女 3 。
深拷贝值:lee 男 3 。
直接拷贝值:赵 女 1 。
结果:上述可以说是对深浅拷贝中经常遇到的几种类型做出总结和对比,相信在一番体悟后可以学到一些知识.
实例2:
class Program { static void Main(string[] args) { int[] numbers = { 2, 3, 4, 5 }; int[] numbersCopy = new int[5]; numbers.CopyTo(numbersCopy, 0); numbersCopy[2] = 0,
。
int[] numbers1 = { 2, 3, 4, 5 }; int[] numbersClone1 = (int[])numbers1.Clone(); numbersClone1[2] = 0,
Console.Write(numbers[2] + "---" + numbersCopy[2]);//4---0 Console.Write(numbers1[2] + "---" + numbersClone1[2]);//4--0 。
//数组的复制也就是引用传递,指向的是同一个地址 int[] numbers2 = { 2, 3, 4, 5 }; int[] numbers2Copy = numbers2; numbers2Copy[2] = 0,
Console.Write(numbers2[2]);//0 Console.Write(numbers2Copy[2]);//0 。
Console.Read(); } } 。
暂不做分析,认真领悟.
最后此篇关于浅谈.net平台下深拷贝和浅拷贝的文章就讲到这里了,如果你想了解更多关于浅谈.net平台下深拷贝和浅拷贝的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
免责声明 这篇文章是关于术语“浅拷贝”和“深拷贝”的正确用法,特别是在谈论复制一个不包含任何引用的对象时。这个问题并不意味着(也不应该)基于意见,除非真的没有关于这个话题的共识。我已将此问题标记为 C
我有这个功能 int getrelation(string name, RELATION& output){ bool found=0; int index=0;
与 why should I make a copy of a data frame in pandas 有关 我注意到在流行的backtesting图书馆, def __init__(self, d
我的问题很基础,但我想 100% 理解所有内容。 SO中的很多问题都引用了我的帖子,但我没有找到满意的答案。 我们知道java中的枚举是引用类型。让我们考虑以下片段: public static cl
请引用这个 fiddle 的问题。 http://jsfiddle.net/AQR55/ 1)为什么附加到隔离范围属性的 watch - 双向绑定(bind)到父属性,不会在更改父范围属性时触发。 在
我想使用 UP3 来完成一项非常具体的任务,我应该能够使用 API 来实现该任务。我想了解是否可以编写以下应用程序。 基于https://jawbone.com/support/articles/00
如何在辅助方法中传递上下文并提取数据? 请参阅以下代码片段: import AppContext from '../../context/AppContext' import extractDatta
我正在尝试使用 simple-git 创建浅克隆。我正在尝试创建与此命令等效的命令:git clone --depth 1 https://github.com/steveukx/git-js.git
我是一名优秀的程序员,十分优秀!