C#对象深度克隆

有基础的开发者都应该很明白,对象是一个引用类型,例如:

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;
        }
    }
}



本文转自 sshpp 51CTO博客,原文链接:http://blog.51cto.com/12902932/1949344,如需转载请自行联系原作者

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值