近日,想整理下我自己的vb.net应用程序中,自己定义的类、控件、窗体等对象,希望能够获得它们的“属性”、“字段”、“方法”、“事件”等名称。查阅了“反射”(Reflection)相关资料,写了以下一段代码,分享给朋友们。
当然,由于本人的水平有限,有些功能还没完善,比如“按对象名排序”的问题,比如“获得属性、方法的参数”的问题,等等。此文抛砖引玉,希望能够得到大侠们的指点。
Private Sub GetAssemblyObject(ByVal lAssembly As Reflection.Assembly)
Dim TT1, TT2, TT3 As String '为输出代码长度,分别代表1、2、3个vbTab
TT1 = vbTab
TT2 = vbTab & vbTab
TT3 = vbTab & vbTab & vbTab
Dim s As String
Dim t, t1() As Type
s = lAssembly.FullName
t1 = lAssembly.GetTypes
'20200312 这里有个未解决的问题,就是需要将t1,g1等对象按名称进行排序
Try
System.Array.Sort(t1) '这个是要报错的
Catch ex As Exception
Dim kkk As String = ""
End Try
s = s.Split(",").GetValue(0)
s = "C:\temp\temp_" & s & ".txt" '保存位置 '文本文件的读写
Dim oSWrit As System.IO.StreamWriter = System.IO.File.CreateText(s)
For Each t In t1
s = ""
oSWrit.WriteLine("===================================================")
If t.IsSubclassOf(GetType(System.Windows.Forms.Form)) = True Then
s = "【窗体】"
ElseIf t.IsSubclassOf(GetType(System.Windows.Forms.UserControl)) = True Then
s = "【控件】"
Else
s = "【对象】"
End If
s = "【" & t.FullName & "】" & TT1 & s & TT1 & t.FullName.Replace(t.Name, "") & TT1 & " 继承自:" & t.BaseType.FullName '要是能够得到文件名就好了
oSWrit.WriteLine(s)
'oSWrit.WriteLine("---------------------------------------------------")
'以下获取属性方法事件,这种做法有问题:
'得到的信息太多了,多数都是不需要的,如何得到我自己定义的那些东东呢??
Dim g, g1() As PropertyInfo
Dim e, e1() As EventInfo
Dim f, f1() As FieldInfo
Dim m, m1() As MethodInfo
Dim b, b1() As MemberInfo
f1 = t.GetFields(BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.DeclaredOnly) '获取字段
g1 = t.GetProperties(BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.DeclaredOnly) '获取属性
m1 = t.GetMethods(BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.DeclaredOnly) '获取方法
e1 = t.GetEvents(BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.DeclaredOnly) '获取事件
b1 = t.GetMembers(BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.DeclaredOnly) '获取所有,包括属性、方法、字段、事件等
If g1.Length > 0 Then
oSWrit.WriteLine("-----------------属性------GetPropertie------------")
For Each g In g1
s = ""
If g.CanRead = True And g.CanWrite = True Then
s = "读写- "
ElseIf g.CanRead = True And g.CanWrite = False Then
s = "只读- "
ElseIf g.CanRead = False And g.CanWrite = True Then
s = "只写- "
ElseIf g.CanRead = False And g.CanWrite = False Then
s = "不可能"
End If
oSWrit.WriteLine(TT1 & s & g.Name & TT2 & g.PropertyType.ToString & TT3 & t.FullName & "-【属性】")
'g.Name 后面加的信息,主要原因是导入Excel后,方便排序、整理
Next
End If
If e1.Length > 0 Then
oSWrit.WriteLine("-----------------事件------GetEvents ------------")
For Each e In e1
'oSWrit.WriteLine(TT1 & e.Name & MM(e.Name) & TT2 & e.GetType.ToString & TT3 & t.FullName & "-【事件】")
oSWrit.WriteLine(TT1 & e.Name & e.Name & TT3 & TT3 & t.FullName & "-【事件】")
Next
End If
If m1.Length > 0 Then
oSWrit.WriteLine("-----------------方法------GetMethods ------------")
For Each m In m1
s = TT2 & m.IsAssembly & TT1 & m.IsFamily & TT1 & m.IsFamilyAndAssembly & TT1 & m.IsFamilyOrAssembly & TT1 & m.IsPrivate & TT1
s &= m.IsPublic & TT1 & m.IsSpecialName & TT1 & m.IsStatic & TT1 '这些是方法和字段共同的
s &= m.IsAbstract & TT1 & m.IsConstructor & TT1 & m.IsFinal & TT1 & m.IsHideBySig & TT1 & m.IsVirtual & TT1
oSWrit.WriteLine(TT1 & m.Name & TT2 & TT3 & t.FullName & "-【方法】" & s)
'属性中的set、get方法也这里罗列出来了,可以判断 m.Name 是否以“set_”“get_”开头,将其屏蔽,不输出。
'自定义的事件,也会在这里罗列出来, 可以判断 m.Name 是否以“add_”“remove_”开头,将其屏蔽,不输出。
Next
End If
'方法和字段共有的:IsAssembly,IsFamily,IsFamilyAndAssembly,IsFamilyOrAssembly,IsPrivate,IsPublic,IsSpecialName,IsStatic
'方法有的:IsAbstract,IsConstructor,IsFinal,IsHideBySig,IsVirtual,
'字段有的:IsInitOnly,IsLiteral,IsNotSerialized,IsPinvokeImpl,
'获得这些值的目的是方便分析对象属性
If f1.Length > 0 Then
oSWrit.WriteLine(vbCrLf & "-----------------字段------GetFields ------------")
For Each f In f1
s = TT2 & f.IsAssembly & TT1 & f.IsFamily & TT1 & f.IsFamilyAndAssembly & TT1 & f.IsFamilyOrAssembly & TT1 & f.IsPrivate & TT1
s &= f.IsPublic & TT1 & f.IsSpecialName & TT1 & f.IsStatic & TT1 '这些是方法和字段共同的
s &= TT3 & TT3
s &= f.IsInitOnly & TT1 & f.IsLiteral & TT1 & f.IsNotSerialized & TT1 & f.IsPinvokeImpl & TT1
oSWrit.WriteLine(TT1 & f.Name & TT2 & f.FieldType.ToString & TT3 & t.FullName & "-【字段】" & s)
Next
End If
'以下是 获取所有,包括属性、方法、字段、事件等,可以不用输出
If b1.Length > 0 Then
oSWrit.WriteLine("-----------------所有------GetMembers ------------")
For Each b In b1
oSWrit.WriteLine(TT1 & b.Name & TT2 & TT3 & t.FullName & "-【所有】")
Next
End If
oSWrit.WriteLine("===================================================" & vbCrLf & vbCrLf)
Next
oSWrit.WriteLine("------------------------------------结束-")
oSWrit.Close()
End Sub
创建一个windows窗体,添加命令按钮,执行这段代码就OK了。
调用方法是:
GetAssemblyObject(Reflection.Assembly.LoadFrom(”bqbass.dll“)) 'bqbass.dll 是项目文件名
生成的文本文件,部分内容截图:
复制到excel,部分内容截图: