深拷贝1兼容多构造函数

        public static T DeepCloneObject<T>(T obj) where T : class
        {
            //System.String类型似乎比较特殊,复制它的所有字段,并不能复制它本身 
            //不过由于System.String的不可变性,即使指向同一对象,也无所谓 
            //而且.NET里本来就用字符串池来维持 
            if (obj == null || obj.GetType() == typeof(string))
                return obj;
            object newObj = null;
            try
            {
                //尝试调用默认构造函数 
                newObj = Activator.CreateInstance(obj.GetType());
            }
            catch
            {
                //失败的话,只好枚举构造函数了 
                foreach (ConstructorInfo ci in obj.GetType().GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
                {
                    try
                    {
                        ParameterInfo[] pis = ci.GetParameters();
                        object[] objs = new object[pis.Length];
                        for (int i = 0; i < pis.Length; i++)
                        {
                            if (pis[i].ParameterType.IsValueType)
                                objs[i] = Activator.CreateInstance(pis[i].ParameterType);
                            else
                                //参数类型可能是抽象类或接口,难以实例化 
                                //我能想到的就是枚举应用程序域里的程序集,找到实现了该抽象类或接口的类 
                                //但显然过于复杂了 
                                objs[i] = null;
                        }
                        newObj = ci.Invoke(objs);
                        //无论调用哪个构造函数,只要成功就行了 
                        break;
                    }
                    catch
                    {
                    }
                }
            }
            foreach (FieldInfo fi in obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (fi.FieldType.IsValueType || fi.FieldType == typeof(string))
                    fi.SetValue(newObj, fi.GetValue(obj));
                else
                    fi.SetValue(newObj, DeepCloneObject(fi.GetValue(obj)));
            }
            //基类的私有实例字段在子类里检索不到,但它仍占据子类对象的内存空间 
            Deep(newObj, obj);
            return (T)newObj;
        }

        //克隆继承树上的私有实例字段 
        public static void Deep(object newObj, object obj)
        {
            for (Type father = newObj.GetType().BaseType; father != typeof(object); father = father.BaseType)
            {
                foreach (FieldInfo fi in father.GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
                {
                    //只需要处理私有字段,因为非私有成员已经在子类处理过了 
                    if (fi.IsPrivate)
                    {
                        if (fi.FieldType.IsValueType || fi.FieldType == typeof(string))
                        {
                            fi.SetValue(newObj, fi.GetValue(obj));
                        }
                        else
                        {
                            fi.SetValue(newObj, DeepCloneObject(fi.GetValue(obj)));
                        }
                    }
                }
            }
        }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章