国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

淺談VB.NET文章系列之一 --通過例子,淺談反射(Reflection)的應用

2024-07-10 13:00:30
字體:
來源:轉載
供稿:網友
淺談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):這里的類型區分于值類型與引用類型中的類型,它包括類,枚舉,值類型,接口等。菜鳥學堂:

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 水城县| 固原市| 上饶市| 含山县| 东源县| 萨嘎县| 阿克| 海南省| 丹寨县| 河津市| 和平县| 杭锦后旗| 洛阳市| 邵阳市| 双鸭山市| 峡江县| 乐清市| 延长县| 福泉市| 嵊泗县| 丰都县| 错那县| 阆中市| 台南市| 吉木萨尔县| 浮山县| 海林市| 永修县| 灵台县| 高邑县| 宜宾县| 九台市| 迭部县| 张掖市| 宜州市| 广水市| 卓资县| 彩票| 建瓯市| 渭南市| 东安县|