VB.net 反射调用

类库 dll

Public Class Class1

    Public Function Say(ByVal say1 As String) As String
        Return say1
    End Function

    Public Function Add(ByVal add1 As Integer, ByVal add2 As Integer) As Integer
        Return add1 + add2
    End Function
End Classy

有上面的 DLL的反射调用测试

Imports System.Reflection '反射 Assembly
Public Class Form1 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click '首先加载程序集 Dim ass As Assembly = Assembly.LoadFile(Application.StartupPath + "\testdell.dll") '获得程序集中所有的公开的类型集合 Dim types As Type() = ass.GetExportedTypes() ' Dim types As Type = ass.GetType("获取指定名字的类型对象") For Each item As Type In types TextBox1.AppendText(item.Name + vbCrLf) '获取程序集类名 TextBox1.AppendText(item.FullName + vbCrLf) '获取程序集命名空间和类名 TextBox1.AppendText(item.Namespace + vbCrLf) '获取程序集命名空间 Dim sub1() As MethodInfo = item.GetMethods() '获取程序集中的方法名 For Each sub2 As MethodInfo In sub1 TextBox1.AppendText(sub2.Name() + vbCrLf) '获取程序集中的方法名 Next Next Dim type1 As Type = ass.GetType("testdell.Class1") '获取dll中的类的类型 Dim dll As Object = Activator.CreateInstance(type1) '创建构造函数 就是实例化类 Dim m1 As MethodInfo = type1.GetMethod("Add") '找到“Add”的方法 '调用程序集中的方法 触发方法 ( 类实例化后的对象,参数) Dim result As Integer = m1.Invoke(dll, New Object() {3, 6}) Dim m2 As MethodInfo = type1.GetMethod("Say") '找到“Add”的方法 Dim sum As String = m2.Invoke(dll, New Object() {"jfidjfioa"}) TextBox1.AppendText(result.ToString() + vbCrLf) TextBox1.AppendText(sum + vbCrLf) End Sub End Class

  

下面有网络上的案例:

1.前提
Net的应用程序由几个部分:‘程序集’、‘模块’、‘类型’组成。
装配件是.Net应用程序执行的最小单位,编译出来的.dll、.exe都是装配件。
2.概念
反射是获得运行时类型的方式。

概念这里讨论两个问题。

问题一:
运行时类型如何理解?
1.运行时:程序运行期
2.类型:.NET应用程序的几个部分(即上面我们提到的组合部分)
所以再次来理解一下反射就是:反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关
问题二:
那么我们具体能够获得什么呢?

1.Assembly类可以获得正在运行的装配件,也可以动态的加载装配件,以及在装配件中查找类型,并创建该类型的实例。
2.Type类可以获得对象的类型,此包含对象的所有要素:方法、构造器、属性等等,通过Type类可以得到这些要素的,并且调用之。
3.MethodInfo包含方法的,通过这个类可以得到方法的名称、参数、返回值等,并且可以调用之。诸如此类,还有FieldInfo、EventInfo等等,这些类都包含在System.Reflection命名 空间下。
3.命名空间与装配件的关系
机房收费系统的时候看到的一个名字就是命名空间(NameSpace)。在.NET的应用程序中并没有提到这个概念,所以在这里解释一下这个名词。

1.关系
装配件和命名空间的关系不是一一对应,也不互相包含,其实他们是一种多对多的关系;一个装配件里面可以有多个命名空间,一个命名空间也可以在多个装配件中存在。

2.理解
命名空间和装配件两个概念针对的对象都是类型。命名空间描述一个类型是哪一族,也就是只是对类型进行了一下整理就好像我们的文件夹一样。装配件表明了一个类型的位置。
在网上看到了一个很好的例子:
命名空间只是说明一个类型是那个族的,比如有人是汉族、有人是回族;而装配件表明一个类型住在哪里,比如有人住在北京、有人住在上海;那么北京有汉族人,也有回族人,上海有汉族人,也有回族人,这是不矛盾的。

装配件是一个类型位置(居住的地方),那么在一个程序中要使用一个类,就必须告诉编译器这个类住在哪儿,编译器才能找到它,也就是说必须引用该装配件。
那么如果在编写程序的时候,也许不确定这个类在哪里,仅仅只是知道它的名称,就不能使用了吗?答案是可以,这就是反射了,就是在程序运行的时候提供该类型的地址,而去找到它。所以我们就不难理解其实我们应用程序在编译的时候并不需要,那么在应用程序的组成部分中也没有这个概念了。

3.应用
演示一个反射来动态创建对象了动态调用方法的例子

1.创建如图的界面

 

2.添加引用


Imports System.Reflection '添加发射的引用
Imports System.Text

3.代码

Imports System.Reflection '添加发射的引用
Imports System.Text

Public Class Form1

'反射来动态创建对象
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Dim asm As Assembly = Assembly.Load("Net反射机制") '使用程序集来查找
Dim _t As Type() = asm.GetTypes '存放程序集中定义的类型
Dim _type As Type
For Each _type In _t '遍历程序集中全部的类型
If _type.Name = "ROBJ" Then '如果查询到的类型是ROBJ
Dim p As Integer = 811221
Dim obj As Object = System.Activator.CreateInstance(_type, p) '创建程序集中ROBJ类型的对象
Me.TextBox1.Text = obj.MyResult() '对象的属性(存储程序集的名字)
End If
Next
End Sub

'反射来动动态调用方法
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
Dim asm As Assembly = Assembly.Load("Net反射机制") '使用程序集来查找
Dim _t As Type() = asm.GetTypes '存放程序集中定义的类型
Dim _type As Type
For Each _type In _t '遍历程序集中全部的类型
If _type.Name = "ROBJ" Then '如果查询到的类型是ROBJ
Dim p As Integer = 811221
Dim obj As Object = System.Activator.CreateInstance(_type, p) '创建程序集中ROBJ类型的对象
Dim m As MethodInfo = _type.GetMethod("Add") '获得公共方法
Dim result As Integer = m.Invoke(obj, New Object() {1, 33}) '调用当前对象所表示的方法
Me.TextBox1.Text = result '显示方法
End If
Next
End Sub
End Class

添加ROJB类

'项目中添加一个类(用来发射它)

Public Class ROBJ
Private result As Integer = 0 '创建私有变量

'创建构造函数-为result赋值
Public Sub New(ByVal _set As Integer)
result = _set
End Sub

'创建一个添加函数:做了一个简单的加减法
Public Function Add(ByVal x As Integer, ByVal y As Integer) As Integer
Return x + y
End Function

'设置一个结果属性,目的是存储程序集的名字
Public Property MyResult As Integer
Get
Return result
End Get
Set(ByVal value As Integer)
result = value
End Set


End Property
End Class

posted @ 2021-09-23 15:30  浅物  阅读(586)  评论(0)    收藏  举报