C# 深拷贝源码

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

}
发布了84 篇原创文章 · 获赞 77 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/lujiachun1/article/details/78780456