c#实现深拷贝的几种方法
为什么要用到深拷贝呢?比如我们建了某个类Person,并且实例化出一个对象,然后,突然需要把这个对象复制一遍,并且复制出来的对象要跟之前的一模一样,来看下我们一般会怎么做,看代码
public class Person
{
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
Person sourceP = new Person() { Name = "大哥" };
Person copyP = sourceP;
copyP.Name = "大哥大"; // 拷贝对象改变Name值
// 结果都是"大哥",因为实现的是浅拷贝,一个对象的改变都会影响到另一个对象
Console.WriteLine("Person.Name: [SourceP: {0}] [CopyP:{1}]", sourceP.Name, copyP.Name);
Console.Read();
}
}
运行结果如图
可以看到虽然复制了一份sourceP对象,但是修改新对象copyP的Name属性时,居然把原来的sourceP对象的值也改了。这里的原理是因为“=”号,在对引用类型使用时,仅仅是新建一个新的引用变量,然后把引用地址复制给了新的引用变量而已,并没有复制真正的内容,这时候如果需要复制真正内容的话,就需要用到深拷贝的方式了。
几种常见的深拷贝方式
1、利用反射实现
public static T DeepCopyByReflection<T>(T obj)
{
if (obj is string || obj.GetType().IsValueType)
return obj;
object retval = Activator.CreateInstance(obj.GetType());
FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static|BindingFlags.Instance);
foreach(var field in fields)
{
try
{
field.SetValue(retval, DeepCopyByReflection(field.GetValue(obj)));
}
catch { }
}
return (T)retval;
}
2、利用二进制序列化和反序列化
public static T DeepCopyByBinary<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;
}
注意,使用二进制序列化和反序列化时,在需要序列化的类上要加上[Serializable]
[Serializable]
public class Person
{
public string Name { get; set; }
}
3、利用xml序列化和反序列化
public static T DeepCopyByXml<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;
}
c#实现深拷贝的几种方法相关推荐
- 实现深拷贝的几种方法
1.我们怎么去实现深拷贝呢,这里可以递归递归去复制所有层级属性. 这么我们封装一个深拷贝的函数(PS:只是一个基本实现的展示,并非最佳实践) 复制代码 function deepClone(obj){ ...
- js 对象深拷贝、对象数组深拷贝的几种方法总结
写前端的时候经常会遇到对象的拷贝,一般我们会用到深拷贝,深拷贝就是完完整整的将一个对象从内存中拷贝一份出来,放到另一块新开辟的内存中去.向下面这种赋值是浅拷贝,a.b都是对同一块内存进行引用,a.b哪 ...
- 一维数组与对象深拷贝的几种方法(指数组、对象中均无嵌套)
一.万能for循环 直接上代码: var arr = [1, 2, 3, 4, 5]var obj = { name: "aaaaa", age: 16 }var arr2 = c ...
- js中实现深拷贝的4种方法
js中深拷贝的方法 原生js中递归函数拷贝 将数据中所有的数据拷贝下来,对拷贝之后的数据进行修改不会影响到原数据 ,两个对象或数组不共享一块内存 <script>let obj={abc: ...
- JS深拷贝的五种方法
1.JSON方法实现 //_tmp和result是相互独立的,没有任何联系,有各自的存储空间. let deepClone = function (obj) {let _tmp = JSON.stri ...
- JavaScript深拷贝的5种方法
目录 应用场景 方法一 方法二 方法三 方法四 方法五 参考链接 应用场景 JavaScript中,Object是引用类型,把对象objA赋值给objB之后,改变objB的值,objA会跟着改变.这是 ...
- JS实现深拷贝常用的几种方法
JS实现深拷贝常用的几种方法 <!DOCTYPE html> <html lang="en"> <head><meta charset=& ...
- 3种方法实现JS对象深拷贝
相信大家总是在各大博客中看到手写深拷贝这类题目,今天就分享3种方法实现它. 什么是深拷贝? let a = { name: 'jiaqi', age: 100 }; let b = a; 我们知道对象 ...
- arraycopy用法_Java复制(拷贝)数组的4种方法:arraycopy()方法、clone() 方法、copyOf()和copyOfRan...
所谓复制数组,是指将一个数组中的元素在另一个数组中进行复制.本文主要介绍关于 Java 里面的数组复制(拷贝)的几种方式和用法.在 Java 中实现数组复制分别有以下 4 种方法: Arrays 类的 ...
最新文章
- Spring Boot + MDC 实现全链路调用日志跟踪,这才叫优雅!
- CComboBox 类详细说明
- (转) SolrCloud之分布式索引及与Zookeeper的集成
- shell编程服务器维护,简单监测服务器的shell脚本
- Android开发之约束布局平均分布|ConstraintLayout平均分布|约束布局均匀分布|ConstraintLayout均匀分布
- [JavaWeb-MySQL]SQL基本概念,通用语法,分类
- Mysql数据库多实例配置
- [转载] Java字符串分割方法
- linux能秒创虚拟机吗,linux下5秒创建rhel7虚拟机
- 显著性检测(saliency detection)评价指标之KL散度距离Matlab代码实现
- 使用AJAX如何得到数据库当中的值!
- 深度报告 | 4G应用启示录与5G应用展望
- 天地图API 调用影像底图 影像注记 全球境界
- IE浏览器无法下载文件的解决办法(windows服务器)
- WEB开发(2) Servlet
- 孙陶然:创新是最好的生存之道
- IP与MAC绑定的难题
- 腾讯云服务器备案要多久?腾讯云小程序备案流程
- P1460 健康的荷斯坦奶牛
- Python解决线性规划问题
热门文章
- 使用WMI来得到系统的服务
- LOAM进行点云地图创建
- Wonderware INSQL historian SDK开发
- 11月19日绿健简报,星期六,农历十月廿六
- 魔方cfop公式软件_【高级篇】(三)三阶魔方CFOP高级玩法之——F2L
- 解魔方神器开源:摄像头看一眼,就能还原全步骤
- 40个实用JS自定义函数(二)
- Unity学习笔记—二次元日系游戏制作(实践篇-游戏初始化场景制作)
- vue 手机端答题页面_从0开始,手把手教你用Vue开发一个答题App01之项目创建及答题设置页面开发...
- 安卓手机续航测试软件,手机充电功率测试软件-手机充电功率测试app安卓版预约v1.0最新版_5577安卓网...