VB中运用反射原理优化程序代码

来源:互联网 发布:电子数据交换应用 编辑:程序博客网 时间:2024/06/05 08:27
在这个项目里我负责的部分是读取某子系统从数据库导出来的两个XML(不妨假设为A.XML和B.XML)文件并根据文件内容完成本部分的业务工作流程。文件是以共享方式放在服务器上,我只需要获得一个Session访问即可,因为要求是实时读写文件,所以否定了下载到本地进行读写的方法,而为了保证程序生命力和数据的完整性,我决定将文件信息一次性读入程序存储空间,并在业务流程中设定当完成某个特定的步骤后回写一遍AB两文件,其中A文件节点可能有增删B文件只是更新某个标志。

  一开始设计具体类的时候很容易想到构造和文件结构对应的类,使用庞大的DOM对象?哦,我可不需要那么多累赘。现在我把对应AB两文件的类分别写了个大概出来,很简单如下:

Class clsA/B
Property Name1 as string
 ...
End Property
Property Name2 as string
 ...
End Property
 ......
 ......
 ......
End Class
  A,B各需要要一个集合类管理,分别命名为clscolA,clscolB,大概如下:

Public Class clscolA/B
Inherits System.Collections.CollectionBase
Public Function GenerateAson() As clsA/clsB
 'New并返回一个 clsA or clsB
 '初始化属性的工作可以在这里进行
End Function
Public Sub AddSon(ByVal objSon As clsA/clsB)
 '增加一条新纪录
 InnerList.Add(objSon)
End Sub
Public Sub Sort()
 '根据某设定的属性对集合进行排序
 InnerList.Sort(New clsSortByName)
End Sub
'默认Item属性以及更多Method从略
End Class


  好了,现在程序数据的基本框架搭好了,这无疑是十分中庸地解决办法,当然也是十分有效的,本文的主题并不是特别愿意删减这些成熟的代码(当然也仅仅是暂且不动而已)。躯壳已有,剩下的工作就是从文件读取并填充数据,如果你还没有接触过反射或者仅仅限于书本上那点例子,这对你来说可能是一个简单而又枯燥的过程,你于是乎也条件反射似地写起来 

New一个clscolA/B(就叫colA/B吧)然后遍历文件或取一个包含所有记录(目标节点)的NodeList,然后作如下状:

With NodeList
 for i as integer=0 to .Count-1
  Dim objson as clsA/B=colA/B.GenerateAson
  objson.Name1=.item(i).childnodes(x1).innertext
  objson.Name2=.item(i).childnodes(x2).innertext
  ......
  ......
  ......
  colA/B.Addson(objson)
 next i
End With
  这段代码虽然他够用,又看似天衣无缝,但总觉得不对头,当属性达到一定数量,你有没有发现你将会使用了太多的同样的赋值句?小学语文就告诉过我们适当使用排比句可以为文章造势,但是如果你一口气排比了20条,那就是滥用了,笔者这里A文件每一条记录有三十多个Field,B文件也有十多个,如果这样用下来景象肯定巍巍壮观,先估计一下代码量,A文件每条记录按30个Field,B按15个算,赋值过程便是45行,还不包括格式化处理和排错处理,如果考虑程序扩展性,以后要读更多的文件则必然会伴随更多类似的过程出现,写程序和做人一样,要低调,一定要低调啊,有激情的程序员自然不会如此糟蹋自己的代码,是否能用一个函数或过程解决上述问题呢?新方案应用而生,采用反射(Imports/using System.Reflection),一个通用过程解决所有问题。示例函数如下:

Public Shared Function FillFromXML(ByVal NodeName As String, ByVal strPath As String, ByVal objFather As Object) As Boolean
 Try
  With xmlGetList(NodeName, strPath)
   For i As Integer = 0 To .Count - 1
    Dim st As Object = objFather.GenerateAson
    Dim ty As Type = st.GetType
    For Each pp As PropertyInfo In ty.GetProperties
     With DirectCast(.Item(i), XmlElement)
      If .SelectSingleNode(pp.Name.ToUpper) IsNot Nothing Then
       pp.SetValue(st, CType(.SelectSingleNode(pp.Name.ToUpper).InnerText.Trim, String), Nothing)
      End If
     End With
    Next
    objFather.AddSon(st)
   Next
  End With
  Return True
 Catch ex As Exception
  Return False
 End Try
End Function
  使用这个函数,只需要保证集合类clscolA/B有GenerateAson和Addson两个方法以及clsA/B两子类的属性名称与文件中Field保持一致即可。你只需要传递相应A或者B文件的目标节点名,文件路径,以及对应的集合类即可,此时再看一下赋值过程的代码减少了多少,恩,只有8行,这对于笔者则意味着省去了45-8=37行代码,而且丢弃老套的排比句。

  第一阶段战斗算是小试牛刀了一把,如果只算赋值过程代码减少百分数为37/45,接近83%。

 

原创粉丝点击