C# 深拷贝源码

来源:互联网 发布:ubuntu top命令详解 编辑:程序博客网 时间:2024/06/07 17:43
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Xml;using System.Reflection;namespace RTDevSoftFucFrame{    /// <summary>自动存储基类接口    /// 实现GetRTSaveObjID接口, 可在对象内部保存一个string类型对象,    /// 利用RTAutoSaveHelp.MakeRTSaveObjID()函数返回的结果对其初始化,    /// 在GetRTSaveObjID接口实现中返回    /// </summary>    public interface RTAutoSaveInterface    {        string GetRTSaveObjID();    }    /// <summary>自动保存辅助类</summary>    static public class RTAutoSaveHelp    {        // static int Num = 0;        /// <summary>生成存储标示ID号</summary>        /// <returns></returns>        public static string MakeRTSaveObjID()        {            /* 测试用            Console.WriteLine(Num.ToString());            return Num++ + "";            */            Guid NewGuid = Guid.NewGuid();            //Console.WriteLine(NewGuid.ToString());            return NewGuid.ToString();        }    }    /// <summary>对于保存字段的配置特征    /// 用法如 [RTDevSoftFucFrame.RTAutoSaveField(true)]    /// </summary>    [AttributeUsage(AttributeTargets.Field, AllowMultiple = true, Inherited = false)]    public class RTAutoSaveFieldAttribute : Attribute    {        /// <summary>构造函数</summary>        /// <param name="RefOtherObj">是否聚合引用的其他对象</param>        /// <param name="SaveField">是否保存此字段</param>        public RTAutoSaveFieldAttribute(bool RefOtherObj, bool SaveField = true)        {            _RefOther = RefOtherObj;            _SaveThisField = SaveField;        }        private bool _RefOther = false;        public bool RefOther        {            get { return (_RefOther); }            set { _RefOther = value; }        }        private bool _SaveThisField = true;        public bool SaveThisField        {            get { return (_SaveThisField); }            set { _SaveThisField = value; }        }    }    internal class RTAnyObjectLoadInf    {        public List<Object> m_AllObj = new List<Object>();        /// <summary>ID和对象映射关系的字典</summary>        public Dictionary<String, Object> m_AllIdAndObj = new Dictionary<String, Object>();        /// <summary>通过ID获得接口对象</summary>        /// <param name="RTSaveObjID"></param>        /// <returns></returns>        public RTAutoSaveInterface GetRTAutoSaveInterfaceObjFromID(string RTSaveObjID)        {            RTAutoSaveInterface RefObj = null;            for (int j = 0; j < m_AllObj.Count; j++)            {                RTAutoSaveInterface RTAutoSaveInterfaceObj = m_AllObj[j] as RTAutoSaveInterface;                if (RTAutoSaveInterfaceObj != null)                {                    if (RTAutoSaveInterfaceObj.GetRTSaveObjID() == RTSaveObjID)                    {                        RefObj = RTAutoSaveInterfaceObj;                        break;                    }                }            }            return RefObj;        }        /// <summary>通过ID获得普通对象</summary>        /// <param name="RTSaveObjID"></param>        /// <returns></returns>        public Object GetRTObjFromID(string RTSaveObjID)        {   // 查字典获取到对应id的对象            try            {                return m_AllIdAndObj[RTSaveObjID];            }            catch (Exception e)            {                var ex1 = new System.Exception(e.Message);                throw ex1;            }        }        //参照方式的信息        public List<Object> m_ObjParentList = new List<Object>();        public List<String> m_ParNameList = new List<String>();        public List<XmlElement> m_XMLNodeList = new List<XmlElement>();        public List<bool> m_IsList = new List<bool>();                    //是否是List变量    }    /// <summary>保存属性</summary>    internal class RTSaveProperty    {        public XmlElement ParentXMLNode = null;        public XmlDocument Xmldoc = null;    }    /// <summary>保存读取过程中异常信息</summary>    public class RefObjIsNotRTAutoSaveInterfaceException : ApplicationException    {        /// <summary>        /// 默认构造函数        /// </summary>        public RefObjIsNotRTAutoSaveInterfaceException() { }        public RefObjIsNotRTAutoSaveInterfaceException(string message)            : base(message)        { }        public RefObjIsNotRTAutoSaveInterfaceException(string message, Exception inner)            : base(message, inner)        { }    }    /// <summary>对象的自动保存</summary>    public class RTObjectAutoSave    {        private const string RefObjAttStrFlag = "RefObjID_17CB4EAD";        private const string TrueTypeAttStrFlag = "TrueType_17CB4EAD";        private const string ValueAttStrFlag = "Value_17CB4EAD";        private const string TypeAssambleAttStrFlag = "TypeAssamble_17CB4EAD";        private const string IsClassNullAttStrFlag = "IsClassNull_17CB4EAD";        /// <summary>标识是否自编ID</summary>        private static Boolean m_IsMakeID = false;        /// <summary>对象及其id的字典</summary>        private static Dictionary<Object, string> m_ObjIdDict = new Dictionary<object, string>();        /// <summary>引用对象的字典</summary>        private static Dictionary<Object, XmlElement> m_RefObjDict = new Dictionary<object, XmlElement>();        /// <summary>根节点(待完善)</summary>        private static RTObjectTreeNode m_ObjRootNode = new RTObjectTreeNode();        /// <summary>标识对象是否是继承于自动保存接口对象的布尔值(默认为True)</summary>        public static Boolean IsMakeID        {            get { return RTObjectAutoSave.m_IsMakeID; }            set { RTObjectAutoSave.m_IsMakeID = value; }        }        /// <summary>写入一个Object到XMLNode</summary>        /// <param name="SaveRTAnyObject">保存的对象</param>        /// <param name="SaveParentXMLNode">保存到的XMLNode</param>        /// <returns></returns>        public static bool SaveRTObjectToXML(Object SaveRTAnyObject, XmlElement SaveParentXMLNode)        {            if (SaveRTAnyObject is RTAutoSaveInterface) m_IsMakeID = false;            else m_IsMakeID = true;            try            {                // 创建一个保存属性,并将 XmlDoc 和 Xml 节点赋值进去                RTSaveProperty parentSave = new RTSaveProperty();                parentSave.ParentXMLNode = SaveParentXMLNode;                parentSave.Xmldoc = SaveParentXMLNode.OwnerDocument;                //                 Boolean Result = SaveOneRTObject(parentSave, SaveRTAnyObject);                // 如果是自我生成编号即非继承于自动保存接口                if (m_IsMakeID)                    foreach (Object Obj in m_RefObjDict.Keys)                    {   // 对引用对象字典遍历,去对象字典搜索获得值                        if (m_ObjIdDict.Keys.Contains(Obj))                            m_RefObjDict[Obj].Attributes[RefObjAttStrFlag].Value = m_ObjIdDict[Obj];                    }                return Result;            }            catch (RefObjIsNotRTAutoSaveInterfaceException ex)            {                var ex1 = new System.Exception(ex.Message);                throw ex1;            }            finally { }        }        /// <summary>从XMLNode读取Object</summary>        /// <param name="SaveRTAnyObject">读取的对象</param>        /// <param name="SaveParentXMLNode">XMLNode</param>        /// <returns></returns>        public static bool LoadRTObjectFromXML(Object SaveRTAnyObject, XmlElement LoadParentXMLNode)        {            if (SaveRTAnyObject is RTAutoSaveInterface) m_IsMakeID = false;            else m_IsMakeID = true;            // 创建一个保存属性,并将 XmlDoc 和 Xml 节点赋值进去            RTSaveProperty parentSave = new RTSaveProperty();            parentSave.ParentXMLNode = LoadParentXMLNode;            parentSave.Xmldoc = LoadParentXMLNode.OwnerDocument;            return LoadRTObject(parentSave, SaveRTAnyObject);        }        /// <summary>写入一个变量</summary>        /// <param name="parentSave">辅助数据</param>        /// <param name="SaveRTAnyObject">保存的对象</param>        /// <returns></returns>        private static bool SaveOneRTObject(RTSaveProperty parentSave, Object SaveRTAnyObject)        {            Type ClassType = SaveRTAnyObject.GetType();            return SaveRTParWithType(parentSave, SaveRTAnyObject, ClassType);        }        delegate bool SaveParDelagate(XmlElement ParXMLNode, Object SavePar, Type SaveParType);         /// <summary>写入一个变量</summary>        /// <param name="parentSave">辅助数据</param>        /// <param name="SaveRTAnyObject">读取的对象</param>        /// <param name="ClassType">当前读取对象继承层次中的类型</param>        /// <returns></returns>        private static bool SaveRTParWithType(RTSaveProperty parentSave, Object SaveRTAnyObject, Type ClassType)        {            // 获取保存对象类型的基类型            Type BaseClassType = ClassType.BaseType;            // 深拷贝一个保存属性 BaseSave            RTSaveProperty BaseSaveProperty = Copy(parentSave);            // 递归判断,如果基类型是 Object,则退出递归;否则继续递归寻找基类型            if (BaseClassType != null && BaseClassType.FullName != "System.Object" && !BaseClassType.Name.Contains("`"))            {                // 根据基类型创建一个 XmlNode                 XmlElement NewNode = parentSave.Xmldoc.CreateElement("BaseClass_" + BaseClassType.Name);                XmlAttribute RTObjID = parentSave.Xmldoc.CreateAttribute("m_RTObjID_17CB4EAD");                RTObjID.Value = "";                if (m_IsMakeID && !m_ObjIdDict.Keys.Contains(SaveRTAnyObject))                {                    // 自编id                    RTObjID.Value = RTAutoSaveHelp.MakeRTSaveObjID();                    NewNode.Attributes.Append(RTObjID);                    m_ObjIdDict.Add(SaveRTAnyObject, RTObjID.Value);                }                BaseSaveProperty.ParentXMLNode = NewNode;                parentSave.ParentXMLNode.AppendChild(NewNode);                SaveRTParWithType(BaseSaveProperty, SaveRTAnyObject, BaseClassType);            }            FieldInfo[] myFields = ClassType.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);            for (int i = 0; i < myFields.Length; i++)            {                string ParName = myFields[i].Name;                object ParVal = myFields[i].GetValue(SaveRTAnyObject);                //空值保存                if (ParVal == null)                {                    parentSave.ParentXMLNode.SetAttribute(ParName, "null");                    continue;                }                Type ParType = null;                try                {                    //此处必须取变量值得类型,不能取字段类型                    ParType = ParVal.GetType();  //myFields[i].FieldType;                }                catch (Exception ex)                {                    // 抛出异常,引用对象不是自动保存接口                    ex = new RefObjIsNotRTAutoSaveInterfaceException(ClassType.FullName + "中的变量:" +                        ParName + "以RTAutoSaveField特征标记引用方式引用了非RTAutoSaveInterface变量");                    throw ex;                }                bool IsRefOther = false;                bool SaveThisField = true;                object[] attrs111 = myFields[i].GetCustomAttributes(true);                foreach (object obj in attrs111)                {                    RTAutoSaveFieldAttribute att = obj as RTAutoSaveFieldAttribute;                    if (att != null)                    {                        IsRefOther = att.RefOther;                        SaveThisField = att.SaveThisField;                    }                }                //此Field不存储                if (!SaveThisField)                {                    continue;                }                /////////////////////////////////////////匿名方法:保存一个Class类型变量//////////////////////////////////////////                SaveParDelagate SaveParDelagateObj = delegate(XmlElement ParXMLNode, Object SaveParVal, Type SaveParType)                {                    // 如果是引用对象                    if (IsRefOther)                    {                        if (!m_IsMakeID)                        {                            // 将需要保存的数值类型转换为自动保存接口                            RTAutoSaveInterface ItemFDD = SaveParVal as RTAutoSaveInterface;                            // 如果转换后的数值类型为空                            if (ItemFDD == null)                            {   // 抛出异常,引用对象不是自动保存接口                                var ex = new RefObjIsNotRTAutoSaveInterfaceException(ClassType.FullName + "中的变量:" +                                    ParName + "以RTAutoSaveField特征标记引用方式引用了非RTAutoSaveInterface变量");                                throw ex;                            }                            // 为xml节点设置属性为id                            ParXMLNode.SetAttribute(RefObjAttStrFlag, (SaveParVal as RTAutoSaveInterface).GetRTSaveObjID());                        }                        else                        {                            // 为xml节点设置属性id                            if (!m_ObjIdDict.Keys.Contains(SaveParVal))                            {                                if (!m_RefObjDict.ContainsKey(SaveParVal))                                    m_RefObjDict.Add(SaveParVal, ParXMLNode);                                ParXMLNode.SetAttribute(RefObjAttStrFlag, null);                            }                            else                            {                                ParXMLNode.SetAttribute(RefObjAttStrFlag, m_ObjIdDict[SaveParVal]);                            }                        }                    }                    else // 如果不是引用对象                    {                        //存储变量存储时的真实类型,供反序列化时创建真实类型(针对对于基类或dynamic变量引用时如此处理)                        ParXMLNode.SetAttribute(TrueTypeAttStrFlag, SaveParType.FullName);  // 类型名                        ParXMLNode.SetAttribute(TypeAssambleAttStrFlag, SaveParType.Assembly.ManifestModule.Name);  // 程序集名                        // 深拷贝一个辅助数据                        RTSaveProperty NewFIDSaveProperty = Copy(parentSave);                        // 设置其xml节点                        NewFIDSaveProperty.ParentXMLNode = ParXMLNode;                        SaveOneRTObject(NewFIDSaveProperty, SaveParVal);                    }                    return true;                };                 //////////////////////////////////////////////                //值类型                if (!ParType.IsClass || ParType.FullName == "System.String")                {                    if (!ParName.Contains("17CB4EAD"))                        parentSave.ParentXMLNode.SetAttribute(ParName, ParVal.ToString());                }                else if (ParType.FullName.Contains(@"System.Collections.Generic"))                {                    Type[] ListGenTypes = ParType.GetGenericArguments();                    Type GenType = ListGenTypes[0];                    XmlElement NewNode = parentSave.Xmldoc.CreateElement(ParName);                    dynamic ListObj = ParVal;                    for (int j = 0; j < ListObj.Count; j++)                    {                        XmlElement NewNode2 = parentSave.Xmldoc.CreateElement(ParName + "_One");                        Object ItemObj = ListObj[j] as Object;                        if(ItemObj != null)                        {                            Type ItemObjType = ItemObj.GetType();                            if (!ItemObjType.IsClass || ParType.FullName == "System.String")                            {                                Type ListParType = ListObj[j].GetType();                                if (!ListParType.IsClass || ListParType.FullName == "System.String")                                {                                    NewNode2.SetAttribute(TrueTypeAttStrFlag, ListParType.FullName);                                    NewNode2.SetAttribute(ValueAttStrFlag, ListObj[j].ToString());                                }                                else                                {                                    continue;                                }                            }                            else                            {                                SaveParDelagateObj(NewNode2, ItemObj, ItemObjType);                            }                        }                        else                        {                            NewNode2.SetAttribute(IsClassNullAttStrFlag, "true");                        }                        NewNode.AppendChild(NewNode2);                    }                    parentSave.ParentXMLNode.AppendChild(NewNode);                }                else if (ParType.IsClass)                {                    XmlElement NewNode = parentSave.Xmldoc.CreateElement(ParName);                    if (ParVal == null)                    {                        continue;                    }                    SaveParDelagateObj(NewNode, ParVal, ParType);                    parentSave.ParentXMLNode.AppendChild(NewNode);                }            }            return true;        }        /// <summary>读取一个变量</summary>        /// <param name="parentSave">辅助数据</param>        /// <param name="SaveRTAnyObject">读取的对象</param>        /// <param name="AllLoadInf">存储所有读取的数据,及二次赋值时需要的</param>        /// <returns></returns>        private static bool LoadRTObject(RTSaveProperty parentSave, Object SaveRTAnyObject)        {            Type ClassType = SaveRTAnyObject.GetType();            RTAnyObjectLoadInf AllLoadInf = new RTAnyObjectLoadInf();            bool IsLoadOK = LoadRTParWithType(parentSave, SaveRTAnyObject, ClassType, AllLoadInf);            bool IsTwoOK = TwoStepDo(AllLoadInf);            return IsLoadOK && IsTwoOK;        }        //由字符串和值变量类型,解析得到相应的值        private static Object ParseStringToValueObj(string ValueStr, Type ValueType)        {            Object ValueObj = null;            if (ValueStr.Equals("")) return null;            if (ValueType.IsEnum)            {                ValueObj = Enum.Parse(ValueType, ValueStr);            }            else if (ValueType.IsValueType)            {                Type[] FunParTypes = new Type[1];                FunParTypes[0] = typeof(string);                var ValMethod = ValueType.GetMethod("Parse", FunParTypes);                object TemSimpleObj = ValueType.Assembly.CreateInstance(ValueType.FullName);                object ReVal = ValMethod.Invoke(TemSimpleObj, new object[] { ValueStr });                ValueObj = ReVal;            }            else   //String类型            {                ValueObj = ValueStr;            }            return ValueObj;        }        private static Object CreateClassObjFromSaveXMLNode(XmlElement ThisFieldNode)        {            Object ParVal = null;            if (ThisFieldNode != null)            {                string TrueTypeFullName = ThisFieldNode.GetAttribute(TrueTypeAttStrFlag);                string AssambleModuleName = ThisFieldNode.GetAttribute(TypeAssambleAttStrFlag);                if (!string.IsNullOrEmpty(TrueTypeFullName) && !string.IsNullOrEmpty(TrueTypeFullName))                {                    Assembly ParDefAsmb = Assembly.LoadFrom(AssambleModuleName);                    dynamic ParTrueobj = null;                    if (TrueTypeFullName.Equals("System.Double[]"))                    {                        ParTrueobj = Array.CreateInstance(typeof(Double), 100);                    }                    else if (TrueTypeFullName.Equals("System.String"))                    {                        ParTrueobj = Activator.CreateInstance(typeof(String), new char[]{' '});                    }                    else                    {                        ParTrueobj = ParDefAsmb.CreateInstance(TrueTypeFullName, true);                    }                    if (ParTrueobj != null)                    {                        ParVal = ParTrueobj;                    }                }                else                {                    // 通过ID查找到xml节点(可改对象树)                    string RefObjId = ThisFieldNode.GetAttribute(RefObjAttStrFlag);                    XmlDocument XmlDoc = ThisFieldNode.OwnerDocument;                    XmlNode FindNode = null;                    FindNode = SearchNode(XmlDoc.FirstChild, RefObjId, FindNode);                    if (FindNode != null)                    {                        return CreateClassObjFromSaveXMLNode(FindNode as XmlElement);                    }                }            }            return ParVal;        }        /// <summary>读取一个变量</summary>        /// <param name="parentSave">辅助数据</param>        /// <param name="SaveRTAnyObject">读取的对象</param>        /// <param name="ClassType">当前读取对象继承层次中的类型</param>        /// <param name="AllLoadInf">存储所有读取的数据,及二次赋值时需要的</param>        /// <param name="BaseCal">是否基类方式调用</param>        /// <returns></returns>        private static bool LoadRTParWithType(RTSaveProperty parentSave, Object SaveRTAnyObject, Type ClassType, RTAnyObjectLoadInf AllLoadInf, bool BaseCal = false)        {            Type BaseClassType = ClassType.BaseType;            if (!BaseCal)            {                // TODO 添加id和对象的映射关系                AllLoadInf.m_AllObj.Add(SaveRTAnyObject);            }            RTSaveProperty BaseSaveProperty = Copy(parentSave);            if (BaseClassType.FullName != "System.Object")            {                // 找到基类xml节点                if (parentSave.ParentXMLNode == null) return false;                XmlElement SelNode = (XmlElement)parentSave.ParentXMLNode.SelectSingleNode("BaseClass_" + BaseClassType.Name);                BaseSaveProperty.ParentXMLNode = SelNode;                //基类数据读入                LoadRTParWithType(BaseSaveProperty, SaveRTAnyObject, BaseClassType, AllLoadInf, true);            }            // 基类的所有属性            FieldInfo[] AllFields = ClassType.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);            for (int i = 0; i < AllFields.Length; i++)            {                bool IsRefOtherObj = false;     //是否引用其他参数                bool SaveThisField = true;                //读取Field特征参数                {                    object[] FieldAttrs = AllFields[i].GetCustomAttributes(true);                    foreach (object obj in FieldAttrs)                    {                        RTAutoSaveFieldAttribute att = obj as RTAutoSaveFieldAttribute;                        if (att != null)                        {   // 将特征的值取出赋值                            IsRefOtherObj = att.RefOther;                            SaveThisField = att.SaveThisField;                        }                    }                }                //此Field不存储,也不读取                if (!SaveThisField)                {                    continue;                }                string ParName = AllFields[i].Name;                string ParAttributeVal = parentSave.ParentXMLNode.GetAttribute(ParName);                //空值赋值                if (ParAttributeVal == "null")                {                    AllFields[i].SetValue(SaveRTAnyObject, null);                    continue;                }                Object ParVal = null;                //获得字段对应的真实变量                {                    //找到变量存储时的真实类型(针对对于基类或dynamic变量引用时如此处理)                    //动态创建变量,保存时的真实类型                    {                        XmlElement ThisFieldNode = (XmlElement)parentSave.ParentXMLNode.SelectSingleNode(ParName);                        if (ThisFieldNode != null)                        {                            ParVal = CreateClassObjFromSaveXMLNode(ThisFieldNode);                        }                    }                    if (ParVal == null)                    {                        ParVal = AllFields[i].GetValue(SaveRTAnyObject);                    }                    else                    {                        AllFields[i].SetValue(SaveRTAnyObject, ParVal);                    }                }                Type ParType = null;                try                {                    if (ParVal == null) continue;                    ParType = ParVal.GetType();   //考虑到继承问题,不能取字段类型                }                catch (Exception e)                {                    // 抛出异常,引用对象不是自动保存接口                    var ex = new RefObjIsNotRTAutoSaveInterfaceException(ClassType.FullName + "中的变量:" +                        ParName + "以RTAutoSaveField特征标记引用方式引用了非RTAutoSaveInterface变量");                    throw ex;                }                //根据不同类型成员变量                //值类型                if (!ParType.IsClass || ParType.FullName == "System.String")                {                    string SaveVal = parentSave.ParentXMLNode.GetAttribute(ParName);                    Object ValueObj = ParseStringToValueObj(SaveVal, ParType);                    AllFields[i].SetValue(SaveRTAnyObject, ValueObj);                }                else if (ParType.FullName.StartsWith(@"System.Collections.Generic.List`1"))                {                    Type[] ListGenTypes = ParType.GetGenericArguments();                    Type GenType = ListGenTypes[0];                    XmlElement SelNode = (XmlElement)parentSave.ParentXMLNode.SelectSingleNode(ParName);                    if (!IsRefOtherObj)                    {                        for (int j = 0; j < SelNode.ChildNodes.Count; j++)                        {                            XmlElement SelNode2 = SelNode.ChildNodes[j] as XmlElement;                            string ListValueStr = SelNode2.GetAttribute(ValueAttStrFlag);                       //简单类型参数直接保存的值                            string IsNullStr = SelNode2.GetAttribute(IsClassNullAttStrFlag);                 //此变量是空值                            object NewListObj = null;                            if (IsNullStr == "true")                            {                                NewListObj = null;                            }                            else                            {                                if (!string.IsNullOrEmpty(ListValueStr))    //值类型                                {                                    string TrueTypeFullName = SelNode2.GetAttribute(TrueTypeAttStrFlag);                                    Type ListItemTrueType = Type.GetType(TrueTypeFullName);                                    NewListObj = ParseStringToValueObj(ListValueStr, ListItemTrueType);                                }                                else                                {                                    Object NewListMemberObj = null;                                    //创建对象                                    {                                        //找到变量存储时的真实类型(针对对于基类或dynamic变量引用时如此处理)                                        NewListMemberObj = CreateClassObjFromSaveXMLNode(SelNode2);                                        //调用默认构造函数构造                                        if (NewListMemberObj == null)                                        {                                            Type[] tps = new Type[0];                                            object[] obj = new object[0];                                            NewListMemberObj = GenType.GetConstructor(tps).Invoke(obj) as Object;                                        }                                    }                                    //初始化成员赋值                                    {                                        RTSaveProperty NewFIDSaveProperty = Copy(parentSave);                                        NewFIDSaveProperty.ParentXMLNode = SelNode2;                                        LoadRTParWithType(NewFIDSaveProperty, NewListMemberObj, GenType, AllLoadInf);                                    }                                    NewListObj = NewListMemberObj;                                }                            }                            //加入到List中                            var addMethod = ParType.GetMethod("Add");                            addMethod.Invoke((object)ParVal, new object[] { NewListObj });                        }                    }                    else                    {                        AllLoadInf.m_ObjParentList.Add(SaveRTAnyObject);                        AllLoadInf.m_ParNameList.Add(ParName);                        AllLoadInf.m_XMLNodeList.Add(SelNode);                        AllLoadInf.m_IsList.Add(true);                    }                }                else if (ParType.IsClass)                {                    //空值,直接赋值                    if (ParVal == null)                    {                        AllFields[i].SetValue(SaveRTAnyObject, ParVal);                        continue;                    }                    else                    {                        XmlElement NewNode = (XmlElement)parentSave.ParentXMLNode.SelectSingleNode(ParName);                        if (IsRefOtherObj)                        {                            AllLoadInf.m_ObjParentList.Add(SaveRTAnyObject);                            AllLoadInf.m_ParNameList.Add(ParName);                            AllLoadInf.m_XMLNodeList.Add(NewNode);                            AllLoadInf.m_IsList.Add(false);                        }                        else                        {   // 如果不为引用对象                            {                                AllFields[i].SetValue(SaveRTAnyObject, ParVal);                                if (m_IsMakeID)                                {                                    // 找出与对象id字典中对象类型相同的对象的id                                    String RefObjID = (from Par in m_ObjIdDict.Keys                                                       where ParType == Par.GetType()                                                       select m_ObjIdDict[Par]).FirstOrDefault();                                    // 添加映射关系到id与obj的字典                                    if (RefObjID != null && !AllLoadInf.m_AllIdAndObj.Keys.Contains(RefObjID))                                        AllLoadInf.m_AllIdAndObj.Add(RefObjID, ParVal);                                }                                RTSaveProperty NewFIDSaveProperty = Copy(parentSave);                                NewFIDSaveProperty.ParentXMLNode = NewNode;                                LoadRTParWithType(NewFIDSaveProperty, ParVal, ParType, AllLoadInf);                            }                            //parentSave.ParentXMLNode.AppendChild(NewNode);                        }                    }                }            }            return true;        }        private static bool TwoStepDo(RTAnyObjectLoadInf AllLoadInf)        {            for (int i = 0; i < AllLoadInf.m_ObjParentList.Count && i < AllLoadInf.m_ParNameList.Count && i < AllLoadInf.m_XMLNodeList.Count && i < AllLoadInf.m_IsList.Count; i++)            {                //父对象类型                Type ParentType = AllLoadInf.m_ObjParentList[i].GetType();                FieldInfo ParFieldInfo = ParentType.GetField(AllLoadInf.m_ParNameList[i], BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);                Type ParType = ParFieldInfo.FieldType;                if (!AllLoadInf.m_IsList[i])                {                    string RefObjID = AllLoadInf.m_XMLNodeList[i].GetAttribute(RefObjAttStrFlag);                    Object RefObj = null;                    if (!m_IsMakeID)                    {                        RefObj = AllLoadInf.GetRTAutoSaveInterfaceObjFromID(RefObjID) as RTAutoSaveInterface;                        //RTAutoSaveInterface RefObj = AllLoadInf.m_AllObj.Find(p1 => (p1.GetRTSaveObjID() == RefObjID));                    }                    else                    {                        RefObj = AllLoadInf.GetRTObjFromID(RefObjID);                    }                    if (RefObj != null)                    {                        ParFieldInfo.SetValue(AllLoadInf.m_ObjParentList[i], RefObj);                    }                }                else                {                    XmlElement SelNode = AllLoadInf.m_XMLNodeList[i];                    object ParVal = ParFieldInfo.GetValue(AllLoadInf.m_ObjParentList[i]);                    dynamic FDD = ParVal;                    for (int j = 0; j < SelNode.ChildNodes.Count; j++)                    {                        XmlElement SelNode2 = SelNode.ChildNodes[j] as XmlElement;                        string RefObjID = SelNode2.GetAttribute(RefObjAttStrFlag);                        Object RefObj = null;                        if (!m_IsMakeID)                        {                            RefObj = AllLoadInf.GetRTAutoSaveInterfaceObjFromID(RefObjID) as RTAutoSaveInterface;                            //RTAutoSaveInterface RefObj = AllLoadInf.m_AllObj.Find(p1 => (p1.GetRTSaveObjID() == RefObjID));                        }                        else                        {                            RefObj = AllLoadInf.GetRTObjFromID(RefObjID);                        }                        if (RefObj != null)                        {                            var addMethod = ParType.GetMethod("Add");                            addMethod.Invoke((object)ParVal, new object[] { RefObj });                        }                    }                }            }            return true;        }        /// <summary>通过引用对象的ID来找到对应的xml节点</summary>        /// <param name="Node">根节点</param>        /// <param name="RefObjId">ID</param>        /// <param name="FindNode">查找的节点(空)用于传递</param>        /// <returns>查找的节点</returns>        private static XmlNode SearchNode(XmlNode Node, string RefObjId, XmlNode FindNode)        {            if (RefObjId == "") return null;            for (int i = 0; i < Node.Attributes.Count; i++)            {   // 匹配属性                if (Node.Name.StartsWith("BaseClass") && Node.Attributes[i].Value.Equals(RefObjId))                {                    FindNode = Node.ParentNode;                    break;                }            }            if (Node.ChildNodes.Count > 0)            {                foreach (XmlNode Child in Node.ChildNodes)                {                    XmlNode Temp = SearchNode(Child, RefObjId, FindNode);                    if (Temp != null) FindNode = Temp;                }            }            return FindNode;        }        /// <summary>保存属性的深拷贝</summary>        /// <param name="rth"></param>        /// <returns></returns>        private static RTSaveProperty Copy(RTSaveProperty rth)        {            RTSaveProperty NewFIDSaveProperty = new RTSaveProperty();            NewFIDSaveProperty.Xmldoc = rth.Xmldoc;            NewFIDSaveProperty.ParentXMLNode = rth.ParentXMLNode;            return NewFIDSaveProperty;        }    }    /// <summary>拷贝辅助</summary>    public class RTCloneHelp    {        /// <summary>标识对象是否是继承于自动保存接口对象的布尔值(默认为True)</summary>        public static Boolean IsMakeID        {            get { return RTObjectAutoSave.IsMakeID; }            set { RTObjectAutoSave.IsMakeID = value; }        }        /// <summary>对象深拷贝(默认为接口对象)        /// 注意:如果为RTAutoSaveInterface的接口派生对象,则可以直接调用;        /// 若不是接口派生对象,则需要设置IsInterfaceObj为false        /// </summary>        /// <param name="rthAnyObject"></param>        /// <returns></returns>        public static Object DeepClone(Object rthAnyObject)        {            // 创建 XmlDoc,并添加空节点 Root            XmlDocument Tem1 = new XmlDocument();            XmlElement Ele1 = Tem1.CreateElement("Root");            Tem1.AppendChild(Ele1);            // 将源对象保存进 XmlDoc            RTObjectAutoSave.SaveRTObjectToXML(rthAnyObject, Ele1);            // 将 XMLDoc 保存到一个文件            //Tem1.Save(@"C:\Users\jclu\Desktop\Demo.xml");            // 获取到源对象的类型            Type ThisType = rthAnyObject.GetType();            // 通过源对象的类型创建一个新的空对象            Object ParTrueobj = Activator.CreateInstance(ThisType, true);            //RTAutoSaveInterface ReturnAnyObject = ParTrueobj as RTAutoSaveInterface;            // 通过 XmlDoc 为空对象赋值            RTObjectAutoSave.LoadRTObjectFromXML(ParTrueobj, Ele1);            return ParTrueobj;        }    }    /// <summary>任意RT对象</summary>    public class RTAnyObject : RTAutoSaveInterface    {        public RTAnyObject()        {            m_RTObjID = RTAutoSaveHelp.MakeRTSaveObjID();        }        private string m_RTObjID = "";        /// <summary>获得ID</summary>        /// <returns></returns>        public string GetRTSaveObjID()        {            return m_RTObjID;        }    }    /// <summary>树结构(待完善)</summary>    public class RTObjectTreeNode    {        public String NodeID = "";        public Object NodeObj = null;        public XmlElement NodeXmlEle = null;        public RTObjectTreeNode Parent = null;        public List<RTObjectTreeNode> Children = new List<RTObjectTreeNode>();    }}
原创粉丝点击