浅谈VB.NET文章系列之一通过例子,浅谈反射(Reflection)的应用说明

应该说这篇短文根本算不上什么深入的分析性的文章,所以在标题前加上了“浅谈”二字,希望对于一般的读者来说,可以给你一个相对直观些的对反射的认识。 --2005/05/23 于东莞在这里对反射以及反射的概念在最后给出简要的解释。一.用来测试的程序集文件的建立。

首先你需要建立一个类库文件(编译后扩展名为.dll),名字假设为:reflection_newtest

系统会默认地新建一个类文件class1,把它该成我们用来测试的类person

具体代码如下:(类的代码比较简单,这里不做解释,如有不明之处,请查看类的相关文档.)

Public Class person

Public firstname As String

Public lastname As String

Dim m_age As Short

Dim m_emailaddress(4) As String

Public Sub New()

MyBase.new()

End Sub

Public Sub New(ByVal firstname As String,ByVal lastname As String)

Me.firstname = firstname

Me.lastname = lastname

End Sub

Public Property age() As Short

Get

Return m_age

End Get

Set(ByVal Value As Short)

m_age = Value

End Set

End Property

Public Property emailaddress(ByVal index As Short) As String

Get

Return m_emailaddress(index)

End Get

Set(ByVal Value As String)

m_emailaddress(index) = Value

End Set

End Property

Sub sendemail(ByVal msg As String,Optional ByVal priorty As Integer = 1)

Console.WriteLine("message to " & firstname & " " & lastname)

Console.WriteLine("priority " & priorty.ToString)

Console.WriteLine(msg)

End Sub

End Class

二.测试验证的程序

建立一个winform的程序,命名假设为:testreflection

从工具栏里拖两个按钮,命名为button1,button2.

1.在程序的最上面加入引用:

Imports System

Imports System.Reflection

Imports System.Type

2.在button1的click事件里写:

Dim asm As [Assembly] ‘由于assembly是关键字,所以要加[]

asm = Reflection.Assembly.LoadFrom("G:\练习\reflection_newtest\bin\reflection_newtest.dll") ‘这里假设上面的reflection_newtest文件的位置在G:\练习 的文件夹。

Console.WriteLine(asm.FullName) ‘输出完全限定名

Console.WriteLine(asm.Location) ‘获取该文件的基本代码格式的位置

Console.WriteLine(asm.CodeBase) ‘获取最初指定的程序集的位置,一般来说和Location方法很相似

Dim mo As [Module] ‘遍历模块

For Each mo In asm.GetModules

Console.WriteLine(mo.FullyQualifiedName)

Next

Dim ty As Type

For Each ty In asm.GetTypes ‘遍历所有类型的信息

Console.WriteLine(ty.FullName)

Next

‘动态加载一个实例

Dim o As Object = asm.CreateInstance("reflection_newtest.person")

Console.WriteLine("********************")

Console.WriteLine(o.GetType.FullName)

说明: 这里的使用都比较简单,请继续往下看!

3.建立测试的过程

'获取遍历的类型,这里使用了系统类库文件mscorlib.dll

Private Sub testtypeenumeration()

Dim asm As [Assembly] = Reflection.Assembly.Load("mscorlib")

Dim t As Type

For Each t In asm.GetExportedTypes ‘对于当前的文件的测试

If t.IsClass Then ‘如果是类

Console.WriteLine(t.Name & "(class)")

ElseIf t.IsEnum Then ‘如果是枚举

Console.WriteLine(t.Name & "(enum)")

ElseIf t.IsValueType Then ‘如果是值类型

Console.WriteLine(t.Name & "(structure)")

ElseIf t.IsInterface Then ‘如果是接口

Console.WriteLine(Name & "(interface)")

Else ‘其他

'没做处理

End If

Next

End Sub

'获取某一类型的所有信息(这里以string为例)

‘从上面的load与type.gettype可见,他们都是创建assembly的方式

Private Sub testatypememberinfo1()

Dim stringtype As Type = Type.GetType("System.String") '获取指定名称的系统类型,也可以使用type.gettype(string)

Dim minfos() As MemberInfo ‘类型数组

Dim mi As MemberInfo

minfos = stringtype.GetMembers

For Each mi In minfos

Console.WriteLine(mi.Name)

Next

'获得公共的非共享的并且是继承的成员

minfos = stringtype.GetMembers(BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.DeclaredOnly)

‘为了便于看清楚输出,做了间隔

Console.WriteLine("*********************")

For Each mi In minfos

Console.WriteLine(mi.Name)

Next

‘同样的间隔设置

Console.WriteLine("*********************")

'获取所有方法

For Each mi In stringtype.GetMethods

Console.WriteLine(mi.Name)

Next

End Sub

'使用特定的显示某一种类型的方法

Private Sub testatypememberinfo()

Dim stringtype As Type = Type.GetType("System.String") '获取指定名称的系统类型

‘对于特定类型的属性的遍历

Dim pinfos() As PropertyInfo = stringtype.GetProperties

Dim mi As MemberInfo

For Each mi In pinfos

Console.WriteLine(mi.Name)

Next

End Sub

'使用findmember方法对类型的遍历1

Private Sub testfindmember1()

Dim stringtype As Type = Type.GetType("System.String")

‘对于findmembers方法来说,它的参数分别为要获得的类型(可用or组合),筛选条件(可用or组合),

委托函数,传递给委托函数的参数。

Dim minfos() As MemberInfo = stringtype.FindMembers(MemberTypes.Method _

Or MemberTypes.Property,BindingFlags.Instance Or BindingFlags.Public,_

AddressOf filterbyname1,"C")

Dim mi As MemberInfo

For Each mi In minfos

Console.WriteLine(mi.Name)

Next

End Sub

'委托函数一:筛选那些是以C开头的公共的实例的方法和属性(这个函数一旦返回true,意味着是符合要求的)

Private Function filterbyname1(ByVal m As MemberInfo,ByVal filtercriteria As Object) As Boolean

'如果成员名称以筛选函数的第2个参数开始,则返回true

If m.Name.StartsWith(filtercriteria.ToString) Then

Return True

End If

End Function

'使用findmember方法对类型的遍历2

Private Sub testfindmember2()

Dim returntype As Type = Type.GetType("System.Int32")

Dim minfos() As MemberInfo = returntype.FindMembers(MemberTypes.Method Or MemberTypes.Property,_

BindingFlags.Instance Or BindingFlags.Public,AddressOf filterbyname2,returntype)

Dim mi As MemberInfo

For Each mi In minfos

Console.WriteLine(mi.Name)

Next

End Sub

'委托函数二

Private Function filterbyname2(ByVal m As MemberInfo,ByVal filtercriteria As Object) As Boolean

If m.MemberType = MemberTypes.Property Then

Dim pi As PropertyInfo = CType(m,PropertyInfo)

Return (pi.PropertyType Is filtercriteria) '如果该属性的类型与第2个参数相同则返回true

ElseIf m.MemberType = MemberTypes.Method Then

Dim mi As MethodInfo = CType(m,MethodInfo)

Return (mi.ReturnType Is filtercriteria) '如果该方法的返回类型与第2个参数相同则返回true

End If

End Function

'关于重载函数的调用

Private Sub testoverloadmemberinfo()

Dim stringtype As Type = Type.GetType("System.String")

'一个类型数组

Dim argtypes() As Type = {Type.GetType("System.String"),Type.GetType("System.String")}

Dim mi As MemberInfo = stringtype.GetMethod("Compare",argtypes)

Console.WriteLine(mi.Name)

End Sub

'枚举参数类型

Private Sub testcallingsyntax()

Dim stringtype As Type = Type.GetType("System.String")

Dim mi As MethodInfo = stringtype.GetMethod("Copy")

Dim pinfos() As ParameterInfo = mi.GetParameters

Dim i As Integer

'列出参数和参数的类型,中间用/连接

For i = 0 To pinfos.GetUpperBound(0)

Console.WriteLine(pinfos(i).Name & "/" & pinfos(i).ParameterType.ToString)

Next

End Sub

'使用反射创建实例并给属性赋值

Private Sub testreadwriteproperties()

Try

Dim asm As [Assembly] = Reflection.Assembly.LoadFrom("G:\练习\reflection_newtest\bin\reflection_newtest.dll")

Dim ty As Type = asm.GetType("reflection_newtest.person")

Dim m As Object = Activator.CreateInstance(ty)

Dim pi As PropertyInfo = ty.GetProperty("age")

pi.SetValue(m,5S,Nothing) '一定要指定赋值的类型,如是short类型,一定要加s

Console.WriteLine(pi.GetValue(m,Nothing))

Catch ex As Exception

MessageBox.Show(ex.Message)

End Try

End Sub

'测试字符串属性(且含参数)

Private Sub testreadwritepropertytieswithargs()

Try

Dim asm As [Assembly] = Reflection.Assembly.LoadFrom("G:\练习\reflection_newtest\bin\reflection_newtest.dll")

Dim ty As Type = asm.GetType("reflection_newtest.person")

Dim m As Object = Activator.CreateInstance(ty)

Dim pi As PropertyInfo = ty.GetProperty("emailaddress")

Dim params() As Object = {1S} '注意参数类型的严格匹配

pi.SetValue(m," 321 north street",params) 321 north street",params)

Console.WriteLine(pi.GetValue(m,params))

Catch ex As Exception

MessageBox.Show(ex.Message)

End Try

End Sub

'使用invoke方法测试过程

Private Sub testinvokemethod()

Dim asm As [Assembly] = Reflection.Assembly.LoadFrom("G:\练习\reflection_newtest\bin\reflection_newtest.dll")

Dim ty As Type = asm.GetType("reflection_newtest.person")

Dim m As Object = Activator.CreateInstance(ty)

Dim mi As MethodInfo = ty.GetMethod("sendemail")

'定义过程的参数数组

Dim params(mi.GetParameters.Length - 1) As Object

Try

params(0) = "this is message"

params(1) = 3

'触发过程

mi.Invoke(m,params)

Catch ex As Exception

MessageBox.Show(ex.Message)

End Try

End Sub

'使用invokemember方法测试过程

Private Sub testinvokemember()

Dim asm As [Assembly] = Reflection.Assembly.LoadFrom("G:\练习\reflection_newtest\bin\reflection_newtest.dll")

Dim ty As Type = asm.GetType("reflection_newtest.person")

Dim m As Object = Activator.CreateInstance(ty)

Dim args() As Object = {"francesco"}

Try

'设置firstname字段值

ty.InvokeMember("firstname",BindingFlags.SetField,Nothing,m,args)

'读取firstname字段值,这个时候不用最后一个参数

Dim value As Object = ty.InvokeMember("firstname",BindingFlags.GetField,Nothing)

Console.WriteLine(value.ToString)

Dim args2() As Object = {35S} '注意这里的数组元素的类型一定要严格匹配short类型,

'设置属性值,参数意味着是属性的参数

ty.InvokeMember("age",BindingFlags.SetProperty,args2)

'读取属性值

Dim value1 As Object = ty.InvokeMember("age",BindingFlags.GetProperty,Nothing)

Console.WriteLine(value1.ToString)

Dim args3() As Object = {"this is a message",2}

'触发过程

ty.InvokeMember("sendemail",BindingFlags.InvokeMethod,args3)

Catch ex As Exception

MessageBox.Show(ex.Message)

End Try

End Sub

‘///////////////////////////////////////////////////////////

'动态地创建对象(使用默认地构造函数)

Private Sub testobjectcreation1()

Dim asm As [Assembly] = Reflection.Assembly.LoadFrom("G:\练习\reflection_newtest\bin\reflection_newtest.dll")

Dim ty As Type = asm.GetType("reflection_newtest.person")

Try

Dim m As Object = Activator.CreateInstance(ty)

Console.WriteLine("A {0} object has been created ",m.GetType.Name)

Catch ex As Exception

MessageBox.Show(ex.Message)

End Try

End Sub

'使用带参数的方法(使用带参数的构造函数)

Private Sub testobjectcreation2()

Dim asm As [Assembly] = Reflection.Assembly.LoadFrom("G:\练习\reflection_newtest\bin\reflection_newtest.dll")

Dim ty As Type = asm.GetType("reflection_newtest.person")

Dim params() As Object = {"Joe","Doe"}

Try

Dim o As Object = System.Activator.CreateInstance(ty,params)

Console.WriteLine(o.GetType.Name)

Catch ex As Exception

MessageBox.Show(ex.Message)

End Try

End Sub

'使用调用构造函数的方法来创建对象(实例)这个方法相对来说比较烦琐和麻烦。

Private Sub testobjectcreation3()

Dim asm As [Assembly] = Reflection.Assembly.LoadFrom("G:\练习\reflection_newtest\bin\reflection_newtest.dll")

Dim ty As Type = asm.GetType("reflection_newtest.person")

Dim types() As Type = {GetType(System.String),GetType(String)}

Dim ci As ConstructorInfo = ty.GetConstructor(types) '获得这个有两个字符串参数的构造函数的信息

Dim params() As Object = {"Joe","Doe"} '用来初始化的数组

Dim o As Object = ci.Invoke(params) '执行这个构造函数

Console.WriteLine(o.GetType.Name)

End Sub

4. button2的click事件中写:(该操作就是验证所有的测试过程,为了分辨出是哪个过程的结果,把其他的都暂时注释掉了。你可以根据需要来消除注释。)

'testtypeenumeration()

'testatypememberinfo1()

'testatypememberinfo2()

'testfindmember1()

'testfindmember2()

testoverloadmemberinfo()

'testcallingsyntax()

'testreadwriteproperties()

'testreadwritepropertytieswithargs()

'testinvokemethod()

'testinvokemember()

'testobjectcreation1()

'testobjectcreation2()

'testobjectcreation3()

说明:这里不多做过多地解释,代码中有比较完整的注释。如果有什么疏漏和错误,请指出!谢谢!

相关名词的简单说明: 反射(Reflection):.Net中获取运行时类型信息的方式程序集(Assembly):编译后的.dll和exe文件。可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。类型(type):这里的类型区分于值类型与引用类型中的类型,它包括类,枚举,值类型,接口等。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Format[$] ( expr [ , fmt ] ) format 返回变体型 format$ 强制返回为文本 -------------------------------- 数字类型的格式化 --------------------------------     固定格式参数:     General Number 普通数字,如可以用来去掉千位分隔号     format$("100,1
VB6或者ASP 格式化时间为 MM/dd/yyyy 格式,竟然没有好的办法, Format 或者FormatDateTime 竟然结果和系统设置的区域语言的日期和时间格式相关。意思是尽管你用诸如 Format(Now, "MM/dd/yyyy"),如果系统的设置格式区域语言的日期和时间格式分隔符是"-",那他还会显示为 MM-dd-yyyy     只有拼凑: <%response.write
在项目中添加如下代码:新建窗口来显示异常信息。 Namespace My ‘全局错误处理,新的解决方案直接添加本ApplicationEvents.vb 到工程即可 ‘添加后还需要一个From用来显示错误。如果到这步还不会则需要先打好基础啦 ‘======================================================== ‘以下事件
转了这一篇文章,原来一直想用C#做k3的插件开发,vb没有C#用的爽呀,这篇文章写与2011年,看来我以前没有认真去找这个方法呀。 https://blog.csdn.net/chzjxgd/article/details/6176325 金蝶K3 BOS的插件官方是用VB6编写的,如果  能用.Net下的语言工具开发BOS插件是一件很愉快的事情,其中缘由不言而喻,而本文则是个人首创,实现在了用V
Sub 分列() ‘以空格为分隔符,连续空格只算1个。对所选中的单元格进行处理 Dim m As Range, tmpStr As String, s As String Dim x As Integer, y As Integer, subStr As String If MsgBox("确定要分列处理吗?请确定分列的数据会覆盖它后面的单元格!", _
  窗体代码 1 Private Sub Text1_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single) 2 Dim path As String, hash As String 3 For Each fil
  Imports MySql.Data.MySqlClient Public Class Form1 ‘ GLOBAL DECLARATIONS Dim conString As String = "Server=localhost;Database=net2;Uid=root;Pwd=123456;" Dim con As New MySqlConnection
‘導入命名空間 Imports ADODB Imports Microsoft.Office.Interop   Private Sub A1() Dim Sql As String Dim Cnn As New ADODB.Connection Dim Rs As New ADODB.Recordset Dim S As String   S = "Provider=OraOLEDB.Oracl
Imports System.IO Imports System.Threading Imports System.Diagnostics Public Class Form1 Dim A(254) As String    Function ping(ByVal IP As Integer) As String Dim IPAddress As String IPAddress = "10.0.
VB运行EXE程序,并等待其运行结束 参考:https://blog.csdn.net/useway/article/details/5494084 Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Pr
今天碰到一个问题,登陆的时候,如果不需要验证手机号为空,则不去验证手机号 因为登陆的时候所有的验证信息都存放在一个数组里 Dim CheckUserInfo() As String ={UserBirthday, SecEmail, UserMob, UserSex, RealNameFirst, RealName, CheckCardID, CheckCardType, Contactemail
在VB6.0中,数据访问接口有三种: 1、ActiveX数据对象(ADO) 2、远程数据对象(RDO) 3、数据访问对象(DAO) 1.使用ADO(ActiveX Data Objec,ActiveX数据对象)连接SQL Server 1)使用ADO控件连接 使用ADO控件的ConnectionString属性就可以连接SQL Server,该属性包含一个由分号分隔的argument=value语
注:大家如果没有VB6.0的安装文件,可自行百度一下下载,一般文件大小在200M左右的均为完整版的软件,可以使用。   特别提示:安装此软件的时候最好退出360杀毒软件(包括360安全卫士,电脑管家等,如果电脑上有这些软件的话),因为现如今的360杀毒软件直接会对VB6.0软件误报,这样的话就可能会在安装过程中被误报阻止而导致安装失败,或者是安装后缺乏很多必须的组件(其它的杀毒软件或安全卫士之类的
Private Sub Form_Load() Call conndb End Sub Private Function conndb() Dim cn As New ADODB.Connection Dim rs As New ADODB.Recordset Dim strCn, sql As String Dim db_host As String Dim db_user As String
  PPSM06S70:  Add  moddate  EDITSPRINTJOB:  MAX(TO_CHAR(ETRN.MODDATE, ‘yyyy/mm/dd/HH24:MI AM‘)) ACTUAL_SHIPDATE   4.Test Scenario (1) :Query SQL Test DN:8016578337 SELECT CTRN.TKCTID TRUCK_ID,        
  沒有出現CrystalReportViewer時,須安裝CRforVS_13_0. 新增1個數據集,新增1個數據表,添加二列,列名要和資料庫名一樣. 修改目標Framework 修改app.config, <startup >改成<startup useLegacyV2RuntimeActivationPolicy ="true">  CrystalReport1.rpt增加數據庫專家 在表單
Imports System.Threading Imports System Public Class Form1 Dim th1, th2 As Thread Public Sub Method1() Dim i As Integer For i = 1 To 100 If Me.Label1.BackColor =
Friend Const PROCESS_ALL_ACCESS = &H1F0FFF = 2035711 Friend Const PROCESS_VM_READ = &H10 Friend Const PROCESS_VM_WRITE = &H20 Friend Const PAGE_READONLY = &H2 Friend Const PAGE_READWRITE = &H4 Friend
以下代码随手写的 并没有大量测试 效率也有待提升 如果需要C#的请自行转换 Function SplitBytes(Data As Byte(), Delimiter As Byte()) As List(Of Byte()) Dim i = 0 Dim List As New List(Of Byte()) Dim bytes As New
Imports System.Data.SqlClient Public Class Form1 REM Public conn1 As SqlConnection = New SqlConnection("server=.; Integrated Security=False;Initial Catalog= mydatabase1; User ID= sa;password")