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

浅谈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, 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

            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):这里的类型区分于值类型与引用类型中的类型,它包括类,枚举,值类型,接口等。

时间: 2024-08-30 08:54:31

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

浅谈ADO.NET文章系列之二 — 并发更新冲突的处理

ado 声明:这里只对并发冲突做简单的分析,所以在前面冠以"浅谈"二字,希望大家可以从中看到一般的处理方法和注意的事项,如果有什么疏漏,那也相当地自然,毕竟本人水平有限,还有很多需要提高的地方,希望各位朋友不吝指正!一.为什么会产生并发在我们使用ado.net对数据库中数据进行操作时,很有可能这种操作或类似地操作也在网络内其他用户中进行着,那么就难以避免地会遇到更新操作失败的情况.因为为了更好地提高性能,ado.net采用了断开连接的方式.也就是说要先把数据的副本读取到客户端,那么也容

浅谈如何写文章的标题

浅谈如何写文章的标题 首先,软文标题要抓特色,抓主要关键词 我在创建关于一篇站长百科网站推广的软文标题时,我考虑到站长百科是一个关键词,但太热,不容易被搜索引擎亲睐.由于自己也是一个站长,所以我就站在站长的用户角度着眼,想一下一般的站长朋友会怎么搜,自己平时又是如何搜的,希望得到怎样的结果,经过深入思索与分析,我认为,做为一个想搜索站长百科站点的用户,肯定是想搜到一个既然全面又在业内普遍欢迎的站点,于是我确定了"站长百科第一行业门户网站"为标题,结果百度排名在第一页,带来了有效的流量,

非设计师谈设计(一):胖胡斐谈Apple改版

设计是一件好像人人都能看懂的东西,所以常有设计师抱怨"老板指手划脚"."客户不懂装懂".我们认为,设计是一门综合性极强的学科.可以说,它就是人人都能看懂,只不过,大家都是从自己的角度来看.设计师说"用户体验"说"视觉"说"风格",客户.老板说"商业"说"运营"说"营销",开发工程师说"技术"说"实现".这些都

哎.实习的一些事,其余的几个老板都谈了转正的事情,就没跟我谈

问题描述 今天老板跟几个他招进来的谈了转正的事情,但是没跟我谈.,我是另外一个人招进来的,不知道为什么,是不是不要我了,那我也得想好后路了 解决方案 解决方案二:老板就是让你急,然后压工资解决方案三:别想太多,该来的都会来.解决方案四:应该不是吧,别太担心了,要相信自己解决方案五:不要也没关系,学好本事更重要,自己能力强了,还怕找不到代码工的工作吗?解决方案六:恩.楼主要找好后路了.不然,到时候就被动了.解决方案七:没找你你就去问呗解决方案八:没事,拿一份工资干一份事,不要你了也不一定坏事,你换

浅谈站内文章编辑的基本要点

近来和很多站长朋友聊天的时候,大家都提到站内文章编辑问题,都反映虽然网站已经有一定权重,但是编辑好的文章很多还是没有被收录;有些被收录的文章没有获得相应排名;有了排名跳出率又很高.经过大家讨论得出站内文章以下的编辑要点,仅供参考. 文章排版规范化 排版规范化主要是针对用户体验来说的,一篇有排版的文章明显要好过一些杂乱无章的文章,一个排版规范的文章讲究的是有头有尾有内容,正所谓虎头凤尾猪肚子,很形象的为我们解述了文章基本的排版标准. 网页颜色布置合理 也许你会感到不解,文章的质量和颜色有什么关系,

浅谈Vb中的坐标问题

问题 vb中的Form,Picture等容器类控件都具有和Scale相关的属性,Scale属性其实就是用来实现自定义这些容器的坐标系统的.和Scale有关的属性有:ScaleTop,ScaleLeft,ScaleWidth,ScaleHeight等,下面简单的介绍一下. 默认的坐标系统是容器的左上角的坐标为(0,0),右下角坐标为(Width,Height),为了根据自己的需要来定义坐标系统,那么就用到了Scale相关属性. 通过设置ScaleLeft和ScaleTop来设置左上角的坐标.例如如

浅谈如何提高文章质量的四个技巧

现实生活中,我们都希望能够买那些物美价廉的产品.一方面,产品的包装可以满足人们的心理需求.另一方面,还可以用最低的价格买到自己想要的东西.可是,我们却忽略了最重要的一点,就是我们使用产品的时间,也就是我们能够对这件产品的质量如何.这一点没有考虑到.质量才是一个产品的生命,没有质量,便没有保证.无论任何东西,基本可以通过外在来发现产品的好与坏.同样的道理,一个网站的文章,是否对用户带来一定的实际价值,才是关键点.下面就是我对文章质量的一些总结,希望对你们有帮助. 第一:立意深远,启人深思. 每个人

从我个人的经历浅谈伪原创文章

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 我曾经有写过一段伪原创文章的经历,是在网站上做兼职,帮一个网站写的.我们的写作方式主要从网站上自己采集一些文章来,然后自己改动一下.主要改动的方式有那么几点. 第一,改动标题.第二,第一段自己重写大约一百来字,大都是些总结性的文章,或者直接将原文的第一段删除,然后根据原文的意思按照自己的叙述方式去重塑第一段.第三,中间的段落颠倒一下顺序,将一

浅谈什么样的文章适合网络推广

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 网络推广,可谓是手段繁多,花样迭出,无论是哪种方法,都有其值得称道之处,可在众多推广手段中,我唯独对软文推广情有独钟,最为偏爱!当然,这并非代表我对其他的手段不看重,只是龙有其首,狼有其王,个人认为,在众多推广手段中,软文推广的作用应当排名第一. 也许有朋友看到此论调之时,或大为不满,斥之为异论,但今日只为阐述自己的一份见解,便不来讨论这软文