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

    这样你就实现了深度拷贝

  • 相关阅读:
    Queryable.Union 方法实现json格式的字符串合并
    战舰少女官方网站正式开启 -手机卡牌游戏
    星工场逆转娱乐圈预计5.1后上线
    Eclipse编辑jsp卡死解决方案
    Eclipse的workspace中放入Ext JS卡死或OOM的解决方案
    Ext Js详解指南
    Android 自定义RadioButton实现
    反编译Android APK及防止APK程序被反编译
    Android自定义控件
    优秀博客
  • 原文地址:https://www.cnblogs.com/unityzc/p/8000326.html
Copyright © 2011-2022 走看看