现在的位置: 首页 > 综合 > 正文

C#反射实践续

2013年08月18日 ⁄ 综合 ⁄ 共 4708字 ⁄ 字号 评论关闭
  前回在C#反射实践的文章中,只介绍了利用反射如何把Xml文件中的数据读取设定到类对象的属性中的方法,这回来介绍如何利用反射机制把值对象写入Xml文件的方法
  本文介绍的把值对象写入Xml文件的方法,有以下几点约束
  1、值对象中的所有属性必须是string类型的,不含保存子节点信息的属性;
  2、自节点数据是保存在范型List中的值对象。
  下面的saveToFile()方法是详细的代码实现,

首先需要在类文件中引入以下.Net的命名空间:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Xml;
  5. using System.Reflection;
  6. using System.IO;

代码实现:saveToFile()方法,

  1.         /// <summary>
  2.         ///  把指定的值对象的属性值保存到Xml文件中相应的节点中,并保存到文件中
  3.         /// </summary>
  4.         /// <param name="obj">需要保存的值对象</param>
  5.         /// <param name="parentNode">保存值对象数据的父节点</param>`
  6.         /// <param name="nodeIndex">子节点的索引</param>
  7.         /// <history>
  8.         private void saveToFile(object obj, XmlNode parentNode, int nodeIndex)
  9.         {
  10.             //取得类名称,作为xml文件的节点名。
  11.             string nodeName = obj.GetType().Name;
  12.             //取得指定对象的属性
  13.             PropertyInfo[] proLst = obj.GetType().GetProperties();
  14.             //准备保存值对象属性值得xml的节点对象。
  15.             XmlNode node = null;
  16.             //取得节点的个数
  17.             int nodeCount = xmlDoc.GetElementsByTagName(nodeName).Count;
  18.             //节点存时,取得已经存在的节点
  19.             if (nodeIndex < nodeCount)
  20.             {
  21.                 node = xmlDoc.GetElementsByTagName(nodeName).Item(nodeIndex);
  22.             }
  23.             //节点不存在时,创建一个新的节点,并把这个节点追加到xml的文档对象中
  24.             if (node == null)
  25.             {
  26.                 node = xmlDoc.CreateElement(nodeName);
  27.                 if (parentNode == null)
  28.                 {
  29.                     this.rootNode.AppendChild(node);
  30.                 }
  31.                 else
  32.                 {
  33.                     parentNode.AppendChild(node);
  34.                 }
  35.             }
  36.             //把对象的属性值保存到Xml文档对象的对应的节点属性中
  37.             foreach (PropertyInfo pro in proLst)
  38.             {
  39.                 XmlElement xmlE = (XmlElement)node;
  40.                 //属性是值对象的场合,只认string数据类型哦
  41.                 if (pro.PropertyType.Name.IndexOf("String") >= 0)
  42.                 {
  43.                     //设定xml节点的属性值
  44.                     xmlE.SetAttribute(pro.Name, pro.GetValue(obj, null).ToString());
  45.                 }
  46.                 //属性是范型的场合,此默认数据类型是范型List<>
  47.                 else if (pro.PropertyType.IsGenericType == true)
  48.                 {
  49.                     //利用反射取得属性的get方法。
  50.                     MethodInfo m = pro.GetGetMethod();
  51.                     //利用反射调用属性的get方法,取得属性的值
  52.                     object rs = m.Invoke(obj, null);
  53.                     //取得List中的对象数
  54.                     int count = (int)rs.GetType().GetProperty("Count").GetValue(rs, null);
  55.                     for (int i = 0; i < count; i++)
  56.                     {
  57.                         //取得List中指定索引的对象
  58.                         object param = rs.GetType().GetProperty("Item").GetValue(rs, new object[] { i });
  59.                         //第归调用实现子节点的向Xml的文档对象的保存
  60.                         saveToFile(param, node, i);
  61.                     }
  62.                 }
  63.                 //Xml节点对象的场合
  64.                 else
  65.                 {
  66.                     //利用反射取得属性的get方法。
  67.                     MethodInfo m = pro.GetGetMethod();
  68.                     //利用反射调用属性的get方法,取得属性的值
  69.                     object rs = m.Invoke(obj, null);
  70.                     saveToFile(rs, node, 0);
  71.                 }
  72.             }
  73.             //把xml的文档对象保存到指定的xml文件中
  74.             xmlDoc.Save(this.filePath);
  75.         }

注意:在上面的代码要想正常编译,需要声明一下类的字段变量

  1.         //xml文件的路径
  2.         private string filePath;
  3.         //保存xml文件信息的文档对象
  4.         private XmlDocument xmlDoc = null;
  5.         //xml文件的根节点名
  6.         private string rootNodeName = "ReflectionTest";
  7.         //xml文件的根节点对象
  8.         private XmlNode rootNode;

类的构造器请参照下记代码:

  1.        //构造器
  2.         public TestConfig(string configFilePath)
  3.         {
  4.             xmlDoc = new XmlDocument();
  5.             createXmlRootNode(filePath);
  6.             filePath = configFilePath;
  7.         }

上面的createXmlRootNode方法,是用来初始化Xml的文档对象-XmlDocument的,实现方式如下:

  1.         /// <summary>
  2.         ///  初始化XMLDocument对象
  3.         /// </summary>
  4.         /// <param name="fileName">Xml的文件名</param>
  5.         private void createXmlRootNode(string fileName)
  6.         {
  7.             if (File.Exists(fileName) == true)
  8.             {
  9.                 xmlDoc.Load(fileName);
  10.                 rootNode = xmlDoc.GetElementsByTagName(rootNodeName).Item(0);
  11.             }
  12.             else
  13.             {
  14.                 xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0""UTF-8"null));
  15.                 rootNode = xmlDoc.CreateElement(rootNodeName);
  16.                 xmlDoc.AppendChild(rootNode);
  17.             }
  18.         }

saveToFile()方法的调用方法如下:

  1.         /// <summary>
  2.         ///  把指定的值对象的属性值保存到Xml文件中
  3.         /// </summary>
  4.         public void saveToXml()
  5.         {      
  6.             saveToFile(thisnull, 0);
  7.         }

上面代码中的this可以是任意的一个按照本文约束规则编写的值对象,null表示要把这值对象作为Xml文件的根节点进行设置,0这个参数是针对一个值对象中包含有范型List<>类型的字对象的情况,如果没有这种类型,直接设定成0就可以了,如果有请参照saveToFile()方法中第归调用时的设定方法,它的值就是List中对象的索引值。
 
 

抱歉!评论已关闭.