zoukankan      html  css  js  c++  java
  • 深拷贝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)));
                            }
                        }
                    }
                }
            }
  • 相关阅读:
    【POJ2893&HDOJ6620】M &#215; N Puzzle(n*m数码判定)
    idea破解方法
    ORACLE:MERGE INTO
    DOS命令大全
    使用oracle 的 PL/Sql 定时执行一个存储过程
    spring RestTemplate用法详解
    Oracle截取字符串和查找字符串
    PLSQL Developer常用设置及快捷键
    IntelliJ IDEA设置自动导入包
    Git使用详细教程
  • 原文地址:https://www.cnblogs.com/Wilson6/p/13300076.html
Copyright © 2011-2022 走看看