近日,想整理下我自己的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 & vbTabDim 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 Trys = 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 Ifs = "【" & 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 IfoSWrit.WriteLine("===================================================" & vbCrLf & vbCrLf)
Next
oSWrit.WriteLine("------------------------------------結束-")
oSWrit.Close()
End Sub
創建一個windows窗體,添加命令按鈕,執行這段代碼就OK了。
調用方法是:
GetAssemblyObject(Reflection.Assembly.LoadFrom(”bqbass.dll“)) 'bqbass.dll 是項目文件名
生成的文本文件,部分內容截圖:
複製到excel,部分內容截圖: