通过c#类型基础了解到变量在内存中的状态,那么我现在想把一个变量传递给另一个变量,对值和对象进行复制。实际上浅度复制是把栈中的数据复制下来,深度复制是把堆上的值进行复制

那么什么时候使用深复制什么时候来使用浅复制呢,假如我请求一次数据库获取到这个对象,再创建新对象的时候可能会用复制的方式来创建这个对象,而不是再去请求一次数据库。

浅复制

先看一段代码,

class Program{static void Main(string[] args){int a = new int();a = 3;int b = a;a += 1;People peo = new People() { age = 19 };People peo2 = peo;peo.age = 20;Console.WriteLine("b={0},peo2={1}", b, peo2.age); //输出b=3,peo2=20Console.Read();}}public class People{public int age;}

结论:浅复制是将栈中的值复制一份,也就是值类型把这个值本身复制一份,操作原来的值对新值没有影响。引用类型是把栈上的引用值复制一份,对象本身不复制,操作对象,新对象也会跟着变化。

深复制:

上面已经介绍了浅拷贝的实现方式,那深拷贝要如何实现呢?在前言部分已经介绍了,实现深拷贝的方式有:反射、反序列化和表达式树。表达式树这里还不是很清晰,持续更新吧。

// 利用反射实现深拷贝public static T CopyWithReflection<T>(T obj){Type type = obj.GetType();// 如果是字符串或值类型则直接返回if (obj is string || type.IsValueType) return obj;if (type.IsArray){Type elementType = Type.GetType(type.FullName.Replace("[]", string.Empty));var array = obj as Array;Array copied = Array.CreateInstance(elementType, array.Length);for (int i = 0; i < array.Length; i++){copied.SetValue(DeepCopyWithReflection(array.GetValue(i)), i);}return (T)Convert.ChangeType(copied, obj.GetType());}object retval = Activator.CreateInstance(obj.GetType());PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic| BindingFlags.Instance | BindingFlags.Static);foreach (var property in properties){var propertyValue = property.GetValue(obj, null);if (propertyValue == null)continue;property.SetValue(retval, DeepCopyWithReflection(propertyValue), null);}return (T)retval;}
//反序列化的实现方式,反序列化的方式也可以细分为3种,具体的实现如下所示:// 利用XML序列化和反序列化实现public static T CopyWithXmlSerializer<T>(T obj){object retval;using (MemoryStream ms = new MemoryStream()){XmlSerializer xml = new XmlSerializer(typeof(T));xml.Serialize(ms, obj);ms.Seek(0, SeekOrigin.Begin);retval = xml.Deserialize(ms);ms.Close();}return (T)retval;}// 利用二进制序列化和反序列实现public static T CopyWithBinarySerialize<T>(T obj){object retval;using (MemoryStream ms = new MemoryStream()){BinaryFormatter bf = new BinaryFormatter();// 序列化成流bf.Serialize(ms, obj);ms.Seek(0, SeekOrigin.Begin);// 反序列化成对象retval = bf.Deserialize(ms);ms.Close();}return (T)retval;}// 利用DataContractSerializer序列化和反序列化实现public static T DeepCopy<T>(T obj){object retval;using (MemoryStream ms = new MemoryStream()){DataContractSerializer ser = new DataContractSerializer(typeof(T));ser.WriteObject(ms, obj);ms.Seek(0, SeekOrigin.Begin);retval = ser.ReadObject(ms);ms.Close();}return (T)retval;}

为了方便测试,就用反序列化的方式来进行测试:

class Program{static void Main(string[] args){People peo = new People() { age = 18 };People peo2 = (People)peo.Clone();peo.age = 20;Console.WriteLine("peo.age={0},peo2.age={1}", peo.age, peo2.age);//输出:peo.age=20,peo2.age=18Console.Read();}}[Serializable]public class People{public int age;public object Clone(){BinaryFormatter bf = new BinaryFormatter();MemoryStream ms = new MemoryStream();bf.Serialize(ms, this);ms.Position = 0;return (bf.Deserialize(ms)); ;}}

结论就不罗嗦了复制就这么回事,主要是理解,理解变量在内存中是怎么变化的。其实js里面的深浅复制也是这么回事。

谢谢大家观看!

深入解析浅复制和深复制相关推荐

  1. 深度解析javascript中的浅复制和深复制

    在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null,Undefined,Object五种类型.而Obje ...

  2. java自我复制_原型模式--自我复制(结合Java浅复制与深复制)

    原型模式,字面上的理解,以原型为标杆的模式. 原型模式其实就是从一个对象再创建另外一个可定制对象,而且不需知道任何创建的细节. 我们可以用原型示例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. ...

  3. android 浅复制与深复制

    今天,简单讲讲  android 浅复制与深复制的内容. 一.前言 任何变成语言中,其实都有浅拷贝和深拷贝的概念,Java 中也不例外.在对一个现有的对象进行拷贝操作的时候,是有浅拷贝和深拷贝之分 ...

  4. JAVA中浅复制与深复制

    來源:http://coolmist.javaeye.com/blog/127455 1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引 ...

  5. python浅复制与深复制_Python中的浅复制与深复制

    python浅复制与深复制 In python, the assignment operator does not copy the objects, instead, they create bin ...

  6. 详解Python中的浅复制与深复制

    列表对象的copy()方法返回列表的浅复制.所谓浅复制,是指生产一个新的列表,并且把原列表中所有元素的引用都复制到新列表中.如果原列表中只包含整数.实数.复数等基本类型或元组.字符串这样的不可变类型, ...

  7. java引用复制_Java中引用的浅复制和深复制

    Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的. 下面来看一个关于引用的例子. package referenceCopy; // ...

  8. 也来谈一谈js的浅复制和深复制

    2019独角兽企业重金招聘Python工程师标准>>> 1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制 ...

  9. C++ 浅复制、深复制详解

    文章目录 浅复制 深复制 有关浅复制与深复制的定义为:对类进行复制的时候按位复制,即把一个对象各数据成员的值原样复制到目标对象中.当类中涉及到指针类型数据成员的时候,往往就会产生指针悬挂问题. 浅复制 ...

  10. Java中Cloneable接口的浅复制与深复制

    Java中的深拷贝(深复制)和浅拷贝(浅复制) 深拷贝(深复制)和浅拷贝(浅复制)是两个比较通用的概念,尤其在C++语言中,若不弄懂,则会在delete的时候出问题,但是我们在这幸好用的是Java.虽 ...

最新文章

  1. python学习一(python与pip工具下载与安装)
  2. html5 div 鼠标跟随,CSS实用:DIV+CSS打造跟随鼠标的层
  3. 数据蒋堂 | 做基础软件要投入很多钱?
  4. Java基础笔记18
  5. 2017年09月23日普级组 树塔狂想曲
  6. 装AJAX.NET 1.0的环境,我遇到个问题,进来解答下
  7. 刷圈兔下载_刷圈兔app
  8. 如何使用Ubuntu打电话
  9. 开发短信发送程序的几则技巧
  10. Hive原理及其使用(六)
  11. 【机器学习】十大 Java 机器学习工具和库
  12. Caused by: org.springframework.web.client.RestClientException: Error while extracting response for t
  13. Orz是什么意思……
  14. 互联网的裁员潮,从业者该怎么样应对?
  15. access偏移注入
  16. 数据仓库工程师面试经验(2019)
  17. 【PAT】B1032 挖掘机技术哪家强 (20 分)_C语言实现
  18. ​史上解释CRC最清楚的文章
  19. Bugly 多渠道热更新解决方案
  20. 智能语音应用开发之DPL2.0高级特性

热门文章

  1. libjpeg-turbo(2)
  2. Java包装类型对象比较相等性注意事项
  3. LeetCode 47 全排列 II
  4. builtins.TypeError: sequence item 0: expected a bytes-like object, str found
  5. 打印Python当前版本详细信息
  6. C语言中二维数组名与数组地址、首行地址、首行首元素地址关系与区别详解(初学者必须掌握)
  7. 01_13_JSP编译指令
  8. 069 Sqrt(x) 求平方根
  9. JVM学习--(二)内存模型、可见性、指令重排序
  10. DeepNude已迅速下线,来看看它涉及的图像修复技术