zoukankan      html  css  js  c++  java
  • 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;
        }

    这样你就实现了深度拷贝

  • 相关阅读:
    Predicting survival from colorectal cancer histology slides using deep learning: A retrospective multicenter study翻译
    pytorch加载训练好的模型用来测试或者处理-finetuning-微调-转移学习
    vgg16 代码 pytorch(nice~)
    git使用命令
    打包时ElementUI使vendor.js文件体量过大优化方法
    webpack打包优化
    hibernate和 mybatis的区别
    java 关于JDBC和DAO模式使用
    JSONP获取JSON数据
    SpringMVC通过CROS协议配置跨域访问
  • 原文地址:https://www.cnblogs.com/unityzc/p/8000326.html
Copyright © 2011-2022 走看看