C#中实现对象的深拷贝(Deep Copy)
C#中实现对象的深拷贝(Deep Copy)
class CsToD
{ //基本思想是:一个对象所占据的内存空间,取决于它的实例字段(包括继承树上的私有实例字段) public T DeepCloneObject<T>(T obj) where T : class { //System.String类型似乎比较特殊,复制它的所有字段,并不能复制它本身 //不过由于System.String的不可变性,即使指向同一对象,也无所谓 //而且.NET里本来就用字符串池来维持 if (obj == null || obj.GetType() == typeof(string)) return obj; object newObj = null; try { //尝试调用默认构造函数 newObj = Activator.CreateInstance(obj.GetType()); } catch { //失败的话,只好枚举构造函数了 foreach (ConstructorInfo ci in obj.GetType().GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { try { ParameterInfo[] pis = ci.GetParameters(); object[] objs = new object[pis.Length]; for (int i = 0; i < pis.Length; i++) { if (pis[i].ParameterType.IsValueType) objs[i] = Activator.CreateInstance(pis[i].ParameterType); else //参数类型可能是抽象类或接口,难以实例化 //我能想到的就是枚举应用程序域里的程序集,找到实现了该抽象类或接口的类 //但显然过于复杂了 objs[i] = null; } newObj = ci.Invoke(objs); //无论调用哪个构造函数,只要成功就行了 break; } catch { } } } foreach (FieldInfo fi in obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (fi.FieldType.IsValueType || fi.FieldType == typeof(string)) fi.SetValue(newObj, fi.GetValue(obj)); else fi.SetValue(newObj, DeepCloneObject(fi.GetValue(obj))); } //基类的私有实例字段在子类里检索不到,但它仍占据子类对象的内存空间 Deep(newObj, obj); return (T)newObj; } //克隆继承树上的私有实例字段 public void Deep(object newObj, object obj) { for (Type father = newObj.GetType().BaseType; father != typeof(object); father = father.BaseType) { foreach (FieldInfo fi in father.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)) { //只需要处理私有字段,因为非私有成员已经在子类处理过了 if (fi.IsPrivate) { if (fi.FieldType.IsValueType || fi.FieldType == typeof(string)) { fi.SetValue(newObj, fi.GetValue(obj)); } else { fi.SetValue(newObj, DeepCloneObject(fi.GetValue(obj))); } } } } } }
class Program
{ static void Main() { Data3 data3 = new Data3(); Data data = new Data(data3); data.PriValue = "Pri"; data.Integer = 3; //修改cloneData对象,并未影响到data对象,说明克隆成功 CsToD ctd = new CsToD(); Data cloneData = ctd.DeepCloneObject(data); cloneData.Integer = 1000; cloneData.PriValue = "clone"; cloneData.Value.D3String = "clonestr"; Console.WriteLine(data.Integer + "<->" + cloneData.Integer); Console.WriteLine(data.PriValue + "<->" + cloneData.PriValue); Console.WriteLine(data.Value.D3String + "<->" + cloneData.Value.D3String); //而如果修改refData对象,data对象也被改变,说明是同一对象 Data refData = data; refData.Integer = 555; refData.PriValue = "ref"; refData.Value.D3String = "refstr"; Console.WriteLine(data.Integer + "<->" + refData.Integer); Console.WriteLine(data.PriValue + "<->" + refData.PriValue); Console.WriteLine(data.Value.D3String + "<->" + refData.Value.D3String); } } class Data:Data2 { public Data(Data3 value) { this.Value = value; } public Data() { } public Data3 Value; } class Data2 { public Data2(int value) { this.Integer = value; } public string PriValue { get { return priValue; } set { priValue = value; } } public Data2() { } public int Integer; private string priValue; } class Data3 { public Data3() { D3String = "D3"; d3Integer = 3; } public string D3String; private int d3Integer; } 来自CSDN博客:http://blog.csdn.net/CsToD/archive/2009/07/29/4390600.aspx
参考文档:
C#用ListView实现XP分组样式(图) C#.Net版本自动更新程序及3种策略实现 C#可拖动窗体(实现无标题栏的登录窗体) C#实现.Net Remoting服务端与客户端通信 C# GridView列头添加CheckBox控件实现全选功能 C#实现DevExpress控件换肤功能 详述IComparer,IComparable接口,实现自定义方法比较对象大小并排序(C#) C#.Net组件开发 - 设计时使用自定义属性编辑器持久化对象 标签:C#.Net组件开发 - 设计时持久化对象数组 C#.Net 持久化对象为XML文件 C#.NET C/S结构版本自动升级解决方案之升级包实现 C#源码-Windows服务管理器,实现安装,卸载,启动和停止服务等功能 【原创】C# 深度拷贝对象 使用.NET反射+递归原理实现深度克隆 C# 实现对象浅拷贝Copy(极速复制对象) C# 克隆对象、复制对象(浅拷贝)、复制对象相同属性的值
其它资料:
什么是C/S结构? | C/S框架核心组成部分 | C/S框架-WebService部署图 | C/S框架-权限管理 | C/S结构系统框架 - 5.1旗舰版介绍 | C/S结构系统框架 - 功能介绍 | C/S结构系统框架 - 产品列表 | C/S结构系统框架 - 应用展示(图) | 三层体系架构详解 | C/S架构轻量级快速开发框架 | C/S框架网客户案例 | WebApi快速开发框架 | C/S框架代码生成器 | 用户授权注册软件系统 | 版本自动升级软件 | 数据库底层应用框架 | CSFramework.CMS内容管理系统 | |