您的位置:首页 > 编程语言 > C#

C#对象深度克隆

2017-06-14 09:52 309 查看
有基础的开发者都应该很明白,对象是一个引用类型,例如:

object b=new object();

object a=b;

那么a指向的是b的地址,这样在有些时候就会造成如果修改a的值,那么b的值也会跟随着改变(a和b是同一个引用内存地址)。

我们想要a和b都是各自互不影响的,那么只能是完全地新建一个新的对象,并且把现有对象的每个属性的值赋给新的对象的属性。也就是值类型的复制,这个操作就叫深度克隆。

这里我们写两个泛型方法分别对对象T和集合List<T>进行深度克隆的实现,我们的方法实现方式是“扩展方法”,就是能在原有的对象后面直接“点”操作。

下面我们来看一下深度克隆的算法实现:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;

/**
* author:qixiao
* create:2017-5-25 11:52:21
* */
namespace QX_Frame.Helper_DG.Extends
{
public static class CloneExtends
{
public static T DeepCloneObject<T>(this T t) where T : class
{
T model = System.Activator.CreateInstance<T>();                     //实例化一个T类型对象
PropertyInfo[] propertyInfos = model.GetType().GetProperties();     //获取T对象的所有公共属性
foreach (PropertyInfo propertyInfo in propertyInfos)
{
//判断值是否为空,如果空赋值为null见else
if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
//如果convertsionType为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
NullableConverter nullableConverter = new NullableConverter(propertyInfo.PropertyType);
//将convertsionType转换为nullable对的基础基元类型
propertyInfo.SetValue(model, Convert.ChangeType(propertyInfo.GetValue(t), nullableConverter.UnderlyingType), null);
}
else
{
propertyInfo.SetValue(model, Convert.ChangeType(propertyInfo.GetValue(t), propertyInfo.PropertyType), null);
}
}
return model;
}
public static IList<T> DeepCloneList<T>(this IList<T> tList) where T : class
{
IList<T> listNew = new List<T>();
foreach (var item in tList)
{
T model = System.Activator.CreateInstance<T>();                     //实例化一个T类型对象
PropertyInfo[] propertyInfos = model.GetType().GetProperties();     //获取T对象的所有公共属性
foreach (PropertyInfo propertyInfo in propertyInfos)
{
//判断值是否为空,如果空赋值为null见else
if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
//如果convertsionType为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
NullableConverter nullableConverter = new NullableConverter(propertyInfo.PropertyType);
//将convertsionType转换为nullable对的基础基元类型
propertyInfo.SetValue(model, Convert.ChangeType(propertyInfo.GetValue(item), nullableConverter.UnderlyingType), null);
}
else
{
propertyInfo.SetValue(model, Convert.ChangeType(propertyInfo.GetValue(item), propertyInfo.PropertyType), null);
}
}
listNew.Add(model);
}
return listNew;
}
}
}


上述代码已经实现了深度克隆的操作,在使用上我们如下:

例如有User类,我们可以这样操作

User user1=new User();

User user2=user1.DeepCloneObject();

这样就完成了对user1的深度克隆!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: