浅复制和深复制
2017-12-30 07:34
169 查看
通过c#类型基础了解到变量在内存中的状态,那么我现在想把一个变量传递给另一个变量,对值和对象进行复制。实际上浅度复制是把栈中的数据复制下来,深度复制是把堆上的值进行复制。
那么什么时候使用深复制什么时候来使用浅复制呢,假如我请求一次数据库获取到这个对象,再创建新对象的时候可能会用复制的方式来创建这个对象,而不是再去请求一次数据库。
浅复制:
先看一段代码,
结论:浅复制是将栈中的值复制一份,也就是值类型把这个值本身复制一份,操作原来的值对新值没有影响。引用类型是把栈上的引用值复制一份,对象本身不复制,操作对象,新对象也会跟着变化。
深复制:
上面已经介绍了浅拷贝的实现方式,那深拷贝要如何实现呢?在前言部分已经介绍了,实现深拷贝的方式有:反射、反序列化和表达式树。表达式树这里还不是很清晰,持续更新吧。
为了方便测试,就用反序列化的方式来进行测试:
结论就不罗嗦了
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/smile.gif)
复制就这么回事,主要是理解,理解变量在内存中是怎么变化的。其实js里面的深浅复制也是这么回事。
谢谢大家观看!
那么什么时候使用深复制什么时候来使用浅复制呢,假如我请求一次数据库获取到这个对象,再创建新对象的时候可能会用复制的方式来创建这个对象,而不是再去请求一次数据库。
浅复制:
先看一段代码,
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=20 Console.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=18 Console.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)); ; } }
结论就不罗嗦了
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/smile.gif)
复制就这么回事,主要是理解,理解变量在内存中是怎么变化的。其实js里面的深浅复制也是这么回事。
谢谢大家观看!
相关文章推荐
- C++复制控制:拷贝构造函数
- tmux 复制与粘贴
- 基于jquery的禁用右键、文本选择功能、复制按键的实现代码
- 无法在“ ”已存在的情况下创建-影像复制该文件
- word文档不允许别人修改和复制的方法
- 你这个创业项目,如果腾讯跟进了,而且几乎是产品上完全复制,你会怎么办?
- 任何文件复制的函数
- MySQL主从复制与读写分离
- 文件复制系统调用版
- IO流复制图片
- JS实现复制到剪贴板功能
- JS将所有对象s的属性复制给对象r(原生js+jquery)
- ORACLE 修改表空间 复制表
- C# 方便的复制/比较物件内数据的方法(Object Copy / Compare)
- 20121011作业——文件复制2 a->b
- 85 复制两个字符串 A 和 B。字符串A的后几个字节和字符串B的前几个字节重叠
- js实现复制内容
- MySQL 5.7.18的安装与主从复制
- MySQL主从复制原理及配置详细过程以及主从复制集群自动化部署的实现
- Mysql学习笔记-复制