VB.Net/Development/Reflection
Содержание
- 1 Define Attributes and Use Reflection to get its value
- 2 Fill Reflection Data into ListView
- 3 Get Class Member and Property Information from base and inherited Class
- 4 Get Method Information
- 5 Get Method information and invoke Method using Reflection API
- 6 Reflection: display the member of Form Class
- 7 Reflection Information for Integer Class
- 8 Reflector Utilities
- 9 Use Reflection to create Class instance and call method
Define Attributes and Use Reflection to get its value
<source lang="vbnet"> Imports System.Reflection
Public Class MainClass
Public Shared Sub Main() Dim MethodObj As System.Reflection.MethodInfo Dim MessageDemo As New Demo() For Each MethodObj In MessageDemo.GetType.GetMethods() Dim Attr As Attribute For Each Attr In MethodObj.GetCustomAttributes(False) Console.WriteLine(MethodObj.Name) Console.WriteLine(Attr) Console.WriteLine(CType(Attr, UserName).Name) Next Next End Sub
End Class
Class UserName
Inherits Attribute Public Name As String Public Sub New(ByVal Name As String) MyBase.New() Me.Name = Name End Sub
End Class Class Demo
<UserName("Name 1")> Sub DemoMsg() Console.WriteLine("Message") End Sub <UserName("Name 2")> Sub Greet() Console.WriteLine("Hello") End Sub
End Class
</source>
Fill Reflection Data into ListView
<source lang="vbnet"> Imports System Imports System.Collections Imports System.Data Imports System.Reflection Imports System.Drawing Imports System.Windows.Forms Imports System.ruponentModel Imports System.Drawing.Drawing2D Imports System.IO Public Class MainClass
Shared Sub Main() Dim form1 As Form = New Form1 Application.Run(form1)
End Sub
End Class
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load " Make column headers. lvwProperties.View = View.Details lvwProperties.Columns.Clear() lvwProperties.Columns.Add("Property", 10, HorizontalAlignment.Left) lvwProperties.Columns.Add("Type", 10, HorizontalAlignment.Left) lvwProperties.Columns.Add("Value", 10,HorizontalAlignment.Left) Dim property_value As Object Dim properties_info As PropertyInfo() = GetType(Form1).GetProperties() lvwProperties.Items.Clear() For i As Integer = 0 To properties_info.Length - 1 With properties_info(i) If .GetIndexParameters().Length = 0 Then property_value = .GetValue(Me, Nothing) If property_value Is Nothing Then ListViewMakeRow(lvwProperties, _ .Name, _ .PropertyType.ToString, _ "<Nothing>") Else ListViewMakeRow(lvwProperties, _ .Name, _ .PropertyType.ToString, _ property_value.ToString) End If Else ListViewMakeRow(lvwProperties, _ .Name, _ .PropertyType.ToString, _ "<array>") End If End With Next i lvwProperties.Columns(0).Width = -2 lvwProperties.Columns(1).Width = -2 lvwProperties.Columns(2).Width = -2 Dim new_wid As Integer = 30 For i As Integer = 0 To lvwProperties.Columns.Count - 1 new_wid += lvwProperties.Columns(i).Width Next i Me.Size = New Size(new_wid, Me.Size.Height) End Sub Private Sub ListViewMakeRow(ByVal lvw As ListView, ByVal item_title As String, ByVal ParamArray subitem_titles() As String) Dim new_item As ListViewItem = lvw.Items.Add(item_title) For i As Integer = subitem_titles.GetLowerBound(0) To _ subitem_titles.GetUpperBound(0) new_item.SubItems.Add(subitem_titles(i)) Next i End Sub
End Class
<Global.Microsoft.VisualBasic.rupilerServices.DesignerGenerated()> _ Partial Public Class Form1
Inherits System.Windows.Forms.Form "Form overrides dispose to clean up the component list. <System.Diagnostics.DebuggerNonUserCode()> _ Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing AndAlso components IsNot Nothing Then components.Dispose() End If MyBase.Dispose(disposing) End Sub "Required by the Windows Form Designer Private components As System.ruponentModel.IContainer "NOTE: The following procedure is required by the Windows Form Designer "It can be modified using the Windows Form Designer. "Do not modify it using the code editor. <System.Diagnostics.DebuggerStepThrough()> _ Private Sub InitializeComponent() Me.lvwProperties = New System.Windows.Forms.ListView Me.SuspendLayout() " "lvwProperties " Me.lvwProperties.Dock = System.Windows.Forms.DockStyle.Fill Me.lvwProperties.Location = New System.Drawing.Point(0, 0) Me.lvwProperties.Name = "lvwProperties" Me.lvwProperties.Size = New System.Drawing.Size(292, 273) Me.lvwProperties.TabIndex = 1 " "Form1 " Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.ClientSize = New System.Drawing.Size(292, 273) Me.Controls.Add(Me.lvwProperties) Me.Name = "Form1" Me.Text = "ReflectionListProperties" Me.ResumeLayout(False) End Sub Friend WithEvents lvwProperties As System.Windows.Forms.ListView
End Class
</source>
Get Class Member and Property Information from base and inherited Class
<source lang="vbnet"> Imports System.Reflection
Public Class MainClass
Public Shared Sub Main() Dim Book = New Derived() Dim Member As MemberInfo Console.WriteLine("Members:") For Each Member In Book.GetType.GetMembers() Console.WriteLine(Member.Name & " " & Member.MemberType) Next Dim PropertyObj As PropertyInfo Console.WriteLine("Properties:") For Each PropertyObj In Book.GetType.GetProperties() Console.WriteLine(PropertyObj.Name & " " & PropertyObj.PropertyType.ToString()) Next Dim MethodObj As MethodInfo Console.WriteLine("Methods:") For Each MethodObj In Book.GetType.GetMethods() Console.WriteLine(MethodObj.Name & " " & MethodObj.ReturnType.ToString()) Next Dim EventObj As EventInfo Console.WriteLine("Events:") For Each EventObj In Book.GetType.GetEvents() Console.WriteLine(EventObj.Name & " " & EventObj.IsMulticast) Next Dim InterfaceObj As Type Console.WriteLine("Events:") For Each InterfaceObj In Book.GetType.GetInterfaces() Console.WriteLine(InterfaceObj.Name) Next End Sub
End Class
Class Base Public ProductID As String Public Weight As Double Private ProductPrice As Double Public Sub New() End Sub Public ReadOnly Property Price() As Double Get Return 0 End Get End Property End Class Class Derived Inherits Base Implements IFormattable Public Title As String Public Author As String Public Publisher As String Public Overridable Overloads Function ToString(ByVal _ Format As String, ByVal Provider As IFormatProvider) _ As String Implements IFormattable.ToString ToString = Title End Function Public Sub New() MyBase.New() End Sub End Class </source>
Get Method Information
<source lang="vbnet"> Imports System.Reflection
Public Class MainClass
Public Shared Sub Main() Dim SomeObj = New Demo() Dim MethodObj As System.Reflection.MethodInfo Console.WriteLine() Console.WriteLine("Methods:") For Each MethodObj In SomeObj.GetType.GetMethods() Console.WriteLine(MethodObj.Name & " " & MethodObj.ReturnType.ToString()) Dim Param As ParameterInfo For Each Param In MethodObj.GetParameters() Console.WriteLine(Param.Name & " " & Param.ParameterType.ToString()) Next Console.WriteLine() Next End Sub
End Class
Class Demo Public Sub A() End Sub Public Sub B(ByVal Msg As String) End Sub Public Function C(ByVal A As Integer, ByVal B As Integer) As Integer End Function Public Sub D(ByVal A As Double, ByVal B As Double, ByVal C As Double) End Sub End Class </source>
Get Method information and invoke Method using Reflection API
<source lang="vbnet"> Imports System.Reflection
Public Class MainClass
Public Shared Sub Main() Dim SomeObj = New Demo() Dim IntegerVar As Integer = 1 Dim DoubleVar As Double = 100.0 Dim StringVar As String = "Hello" Dim Param As ParameterInfo Dim MethodObj As System.Reflection.MethodInfo For Each MethodObj In SomeObj.GetType.GetMethods() Dim Parameters(MethodObj.GetParameters().Length - 1) As Object Dim CallMethod As Boolean = True Dim I As Integer = 0 For Each Param In MethodObj.GetParameters() If Equals(Param.ParameterType, IntegerVar.GetType()) Then Parameters(I) = IntegerVar ElseIf Equals(Param.ParameterType, DoubleVar.GetType()) Then Parameters(I) = DoubleVar ElseIf Equals(Param.ParameterType, StringVar.GetType()) Then Parameters(I) = StringVar Else CallMethod = False End If I = I + 1 Next If (CallMethod) Then If MethodObj.GetParameters().Length = 0 Then Console.WriteLine("Calling: " & MethodObj.Name) Console.WriteLine(MethodObj.Invoke(SomeObj, Nothing)) Else Console.WriteLine("Calling: " & MethodObj.Name) Console.WriteLine(MethodObj.Invoke(SomeObj, Parameters)) End If End If Console.WriteLine() Next End Sub
End Class
Class Demo Public Sub Hello() End Sub Public Sub ShowMessage(ByVal Msg As String) End Sub Public Function AddTwoIntegers(ByVal A As Integer, ByVal B As Integer) As Integer End Function Public Sub ShowThreeDoubles(ByVal A As Double, ByVal B As Double, ByVal C As Double) End Sub End Class </source>
Reflection: display the member of Form Class
<source lang="vbnet"> Imports System Imports System.Collections Imports System.Data Imports System.IO Imports System.Xml.Serialization Imports System.Windows.Forms Imports System.Drawing Imports System.Drawing.Drawing2D Imports System.Drawing.Text Imports System.Drawing.Printing
Public Class MainClass
Shared Sub Main() Dim aForm As New Windows.Forms.Form() Dim aType As Type aType = aForm.GetType() Dim member As Object Console.WriteLine("Members of the Form class") For Each member In aType.GetMembers Console.Write(member.ToString) Next End Sub
End Class
</source>
Reflection Information for Integer Class
<source lang="vbnet"> Imports System public class MainClass
Shared Sub Main() Dim i As Integer = 15 Console.WriteLine(i.ToString()) Console.WriteLine("Hash is: " + i.GetHashCode().ToString()) Console.WriteLine("Type is: " + i.GetType().ToString) Console.WriteLine("Type full name is: " + i.GetType().FullName()) Console.WriteLine("Type assembly qualified name is: " + i.GetType().AssemblyQualifiedName) Console.WriteLine("Namespace is: " + i.GetType().Namespace) End Sub
End Class
</source>
Reflector Utilities
<source lang="vbnet"> Imports System.Windows.Forms <Global.Microsoft.VisualBasic.rupilerServices.DesignerGenerated()> _ Partial Class Reflector
Inherits System.Windows.Forms.Form <System.Diagnostics.DebuggerStepThrough()> _ Private Sub InitializeComponent() Me.lblAssembly = New System.Windows.Forms.Label Me.treeTypes = New System.Windows.Forms.TreeView Me.cmdReflect = New System.Windows.Forms.Button Me.SuspendLayout() " "lblAssembly " Me.lblAssembly.Location = New System.Drawing.Point(10, 9) Me.lblAssembly.Name = "lblAssembly" Me.lblAssembly.Size = New System.Drawing.Size(272, 12) Me.lblAssembly.TabIndex = 5 " "treeTypes " Me.treeTypes.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _ Or System.Windows.Forms.AnchorStyles.Left) _ Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) Me.treeTypes.Location = New System.Drawing.Point(10, 29) Me.treeTypes.Name = "treeTypes" Me.treeTypes.Size = New System.Drawing.Size(362, 276) Me.treeTypes.TabIndex = 4 " "cmdReflect " Me.cmdReflect.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) Me.cmdReflect.Location = New System.Drawing.Point(300, 313) Me.cmdReflect.Name = "cmdReflect" Me.cmdReflect.Size = New System.Drawing.Size(72, 28) Me.cmdReflect.TabIndex = 3 Me.cmdReflect.Text = "Reflect" " "Reflector " Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.ClientSize = New System.Drawing.Size(382, 350) Me.Controls.Add(Me.lblAssembly) Me.Controls.Add(Me.treeTypes) Me.Controls.Add(Me.cmdReflect) Me.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) Me.Name = "Reflector" Me.Text = "Reflector" Me.ResumeLayout(False) End Sub Friend WithEvents lblAssembly As System.Windows.Forms.Label Friend WithEvents treeTypes As System.Windows.Forms.TreeView Friend WithEvents cmdReflect As System.Windows.Forms.Button Private Sub cmdReflect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdReflect.Click treeTypes.Nodes.Clear() Dim MyAssembly As System.Reflection.Assembly MyAssembly = System.Reflection.Assembly.GetExecutingAssembly() lblAssembly.Text = MyAssembly.FullName Dim MyTypes(), MyType As Type Dim MyEvents(), MyEvent As System.Reflection.EventInfo Dim MyMethods(), MyMethod As System.Reflection.MethodInfo Dim MyProperties(), MyProperty As System.Reflection.PropertyInfo MyTypes = MyAssembly.GetTypes() For Each MyType In MyTypes Dim nodeParent As TreeNode = treeTypes.Nodes.Add(MyType.FullName) Dim node As TreeNode = nodeParent.Nodes.Add("Events") MyEvents = MyType.GetEvents For Each MyEvent In MyEvents node.Nodes.Add(MyEvent.Name & " - event handler signature: " & _ MyEvent.EventHandlerType.Name) Next node = nodeParent.Nodes.Add("Methods") MyMethods = MyType.GetMethods() For Each MyMethod In MyMethods node.Nodes.Add(MyMethod.Name) Next node = nodeParent.Nodes.Add("Properties") MyProperties = MyType.GetProperties For Each MyProperty In MyProperties node.Nodes.Add(MyProperty.Name & "- data type: " & _ MyProperty.PropertyType.ToString()) Next Next End Sub
End Class
</source>
Use Reflection to create Class instance and call method
<source lang="vbnet"> Imports System Imports System.Reflection
Public Class MainClass
Shared Sub Main( ) Dim theMathType As Type = Type.GetType("System.Math") Dim paramTypes(0) As Type paramTypes(0) = Type.GetType("System.Double") Dim ConsineInfo As MethodInfo = _ theMathType.GetMethod("Sin", paramTypes) Dim parameters(0) As Object parameters(0) = 45 * (Math.PI / 180) Dim returnVal As Object returnVal = ConsineInfo.Invoke(theMathType, parameters) Console.WriteLine("The sine of a 45 degree angle is {0}", _ returnVal) End Sub
End Class
</source>