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

原创 2005年05月26日 16:13:00

浅谈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()

    Public Sub New()

        MyBase.new()

    End Sub

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

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

      Me.firstname = firstname

      Me.lastname = lastname  

     End Sub

    Public Property age() As Short

    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.在button1click事件里写:

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 ‘如果是枚举

           ElseIf t.IsEnum Then ‘如果是枚举

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

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

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

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

           ElseIf t.IsInterface Then ‘如果是接口

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

            Else ‘其他

                '没做处理

            End If

        Next

    End Sub

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

‘从上面的loadtype.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 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

End Sub

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

    Private Sub testreadwriteproperties()

         Try

         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")

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

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

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

            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)

            Console.WriteLine(pi.GetValue(m, 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

       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, m, Nothing)

            Console.WriteLine(value.ToString)

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

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

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

            '读取属性值

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

            Console.WriteLine(value1.ToString)

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

            '触发过程

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

        Catch ex As Exception

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

'testtypeenumeration()

        'testatypememberinfo1()

        'testatypememberinfo2()

        'testfindmember1()

        'testfindmember2()

        testoverloadmemberinfo()

        'testcallingsyntax()

        'testreadwriteproperties()

        'testreadwritepropertytieswithargs()

        'testinvokemethod()

        'testinvokemember()

        'testobjectcreation1()

        'testobjectcreation2()

        'testobjectcreation3()

 

 

 

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

相关名词的简单说明:

反射(Reflection):.Net中获取运行时类型信息的方式

程序集(Assembly):编译后的.dllexe文件。可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。

类型(type):这里的类型区分于值类型与引用类型中的类型,它包括类,枚举,值类型,接口等。

///////////////////////闵峰

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

                                             

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

应该说这篇短文根本算不上什么深入的分析性的文章,所以在标题前加上了“浅谈”二字,希望对于一般的读者来说,可以给你一个相对直观些的对反射的认识。                             ...

浅谈VB.NET文章系列之一 --通过例子

浅谈VB.NET文章系列之一通过例子,浅谈反射(Reflection)的应用说明:应该说这篇短文根本算不上什么深入的分析性的文章,所以在标题前加上了“浅谈”二字,希望对于一般的读者来说,可以给你一个相...

浅谈VB.NET数组声明和初始化

  • 2013年05月03日 20:30
  • 2KB
  • 下载

浅谈VB.NET中的接口

只支持单继承的VB.NET为了解决多继承的问题,引入了接口的概念。我们可以这样来为接口下一个定义:接口就是指只包含虚成员的虚类。 (1)        虚类,表明了接口是不能够被直接实例化的。也就...

浅谈C# ADO.NET UpdateRowSource 外带简单例子

UpdateRowSource是DbCommand的一个属性,当DbCommand把本地变化更新到数据库的时候,UpdateRowSource可能把数据库的变化带回本地。 用例子来说: 假设有...

浅谈Asp.Net分页与排序技术

  • 2008年11月10日 20:58
  • 242KB
  • 下载

asp.net如何加快页面加载(三)——浅谈正则应用

在这一两年内数据存储以json格式风靡全球。各个大大小小的网站都会使用json格式来存储一些细节或只读(非查询筛选条件)的信息。而在c#后台代码读取json 格式转化为Datatable或者其他对象,...

Asp.Net性能优化浅谈

  • 2011年07月22日 09:03
  • 147KB
  • 下载

【浅谈ASP.NET】——Web服务应用实例

前言  在学习ASP.NET的时候,总是在跟着老师在学习视频里面的小例子,其中在学习web服务的时候,遇到了一些小问题:就是当我们在添加引用的时候,在引用里面没有找到添加web引用这一项,所以就在网上...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:浅谈VB.NET文章系列之一 --通过例子,浅谈反射(Reflection)的应用
举报原因:
原因补充:

(最多只允许输入30个字)