• C# DeepClone 深拷贝


    常规利用反射进行克隆

       public static T CloneModel<T>(T oModel)
        {
            var oRes = default(T);
            var oType = typeof(T);
    
            //create new obj
            oRes = (T)Activator.CreateInstance(oType);
    
            //pass 1 property
            var lstPro = oType.GetProperties();
            foreach (var oPro in lstPro)
            {
                var oValue = oPro.GetValue(oModel,null);
                oPro.SetValue(oRes, oValue, null);
            }
    
            var lstField = oType.GetFields();
            foreach (var oField in lstField)
            {
                var oValue = oField.GetValue(oModel);
                oField.SetValue(oRes, oValue);
            }
            return oRes;
        }

    但是当你克隆的字段中有引用类型的时候并不能真正的拷贝出一个新的如list 

    因此在SetValue的时候 你需要进行深度拷贝

    代码如下可直接使用

    public static object DeepCopy(object obj)
        {
            if (obj == null)
                return null;
            Type type = obj.GetType();
    
            if (type.IsValueType || type == typeof(string))
            {
                return obj;
            }
            else 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(DeepCopy(array.GetValue(i)), i);
                }
                return Convert.ChangeType(copied, obj.GetType());
            }
            else if (type.IsClass)
            {
    
                object toret = Activator.CreateInstance(obj.GetType());
                FieldInfo[] fields = type.GetFields(BindingFlags.Public |
                            BindingFlags.NonPublic | BindingFlags.Instance);
                foreach (FieldInfo field in fields)
                {
                    object fieldValue = field.GetValue(obj);
                    if (fieldValue == null)
                        continue;
                    field.SetValue(toret, DeepCopy(fieldValue));
                }
                return toret;
            }
            else
                throw new ArgumentException("Unknown type");
        }

    使用的话就是在SetValue时 的oValue进行DeepClone即可

     public static T CloneModel<T>(T oModel)
        {
            var oRes = default(T);
            var oType = typeof(T);
    
            //create new obj
            oRes = (T)Activator.CreateInstance(oType);
    
            //pass 1 property
            var lstPro = oType.GetProperties();
            foreach (var oPro in lstPro)
            {
                var oValue = oPro.GetValue(oModel,null);
                oPro.SetValue(oRes, DeepCopy(oValue), null);
            }
    
            var lstField = oType.GetFields();
            foreach (var oField in lstField)
            {
                var oValue = oField.GetValue(oModel);
                oField.SetValue(oRes, DeepCopy(oValue));
            }
            return oRes;
        }

    这样你就实现了深度拷贝

  • 相关阅读:
    (82)zabbix如何选择适合的监控类型
    (80)zabbix性能优化中的几个建议
    (79)zabbix key总是not supported的解决方法
    (78)zabbix值缓存(value cache)说明
    Centos7搭建docker仓库
    centos7安装docker
    Win10调整MTU值
    nginx配置ssl证书
    CentOS7.6配置do.cker和K.B.S
    RAID阵列盘有一块状态变为外来处理方法
  • 原文地址:https://www.cnblogs.com/unityzc/p/8000326.html
Copyright © 2020-2023  润新知