新聞中心

        EEPW首頁(yè) > 測(cè)試測(cè)量 > 設(shè)計(jì)應(yīng)用 > 學(xué)習(xí)LabVIEW(二)——操作.NET泛型類

        學(xué)習(xí)LabVIEW(二)——操作.NET泛型類

        作者: 時(shí)間:2017-01-09 來(lái)源:網(wǎng)絡(luò) 收藏
        誤入歧途的一天。昨天晚上我看見(jiàn)http://digital.ni.com/public.nsf/allkb/DC41DCDA972642CF8625787E00732DDD說(shuō)LabVIEW不支持.NET的泛型,如果要用,可以用C#寫一個(gè)包裝類。我就不信邪了,即使LabVIEW的語(yǔ)言層面不支持,我們也可以用.NET框架提供的Reflection的能力來(lái)實(shí)現(xiàn)任何我們想要實(shí)現(xiàn)的目標(biāo)吧,用不著大動(dòng)干戈寫C#代碼。于是我今天就試了試,最后發(fā)現(xiàn),還是寫C#代碼來(lái)得比較方便,盡管我們用純LabVIEW實(shí)現(xiàn)了泛型類的操作。
        用Reflection這樣的機(jī)制操作泛型類,首先需要對(duì).NET框架的基本對(duì)象模型有些了解。.NET的對(duì)象模型和CPython的對(duì)象模型有許多共通之處,比如,對(duì)象實(shí)例會(huì)包含一個(gè)執(zhí)行類型對(duì)象的指針,這就是可以在運(yùn)行時(shí)獲取對(duì)象類型信息的基石。這里有一個(gè)非常重要的概念,就是類型對(duì)象,所謂類型對(duì)象就是代表類型的對(duì)象,這一點(diǎn)和CPython的對(duì)象模型簡(jiǎn)直不能更像,類型也是對(duì)象。知道了這一點(diǎn),問(wèn)題就好解決了。首先構(gòu)造泛型類填充類型之后的類的對(duì)象,再由類對(duì)象來(lái)生成類實(shí)例。
        我們挑選System.Collections.Generic.Dictionary作為實(shí)驗(yàn)對(duì)象。這個(gè)泛型類我們需要填充兩個(gè)類型參數(shù),一個(gè)是Key的類型,一個(gè)是Value的類型。
        首先,獲取沒(méi)有填充類型參數(shù)的Dictionary類對(duì)象。類對(duì)象可以使用
        System.Type.GetType("類名")
        這種方式獲取。然而,沒(méi)有填充類型的Dictionary的名字是什么呢?在頁(yè)面https://msdn.microsoft.com/zh-cn/library/system.type.makegenerictype(v=vs.100).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-3中C++的例子我們就能發(fā)現(xiàn)它的名字是System.Collections.Generic.Dictionary`2。


        上圖有一點(diǎn)需要注意。“調(diào)用節(jié)點(diǎn)”不僅可以調(diào)用普通的方法,也可以調(diào)用類的靜態(tài)方法。具體做法就是類實(shí)例的輸入端口什么也不接,然后在節(jié)點(diǎn)的右鍵菜單中選擇相應(yīng)的類名。類型選擇的時(shí)候要注意,如果要用System.String, System.Int32, 以及System.Type這些類型時(shí),要去mscorlib中找,選擇器列出來(lái)的項(xiàng)目中沒(méi)有這些,如下圖所示:


        現(xiàn)在我們得到了沒(méi)有填充類型參數(shù)的Dictionary,如何在沒(méi)有語(yǔ)言支持的情況下填充參數(shù)呢(C#等.NET語(yǔ)言提供了語(yǔ)言支持可以用諸如Dictionary這樣的語(yǔ)法)?答案就是MakeGenericType。類型對(duì)象的MakeGenericType方法的參數(shù)為Type[],數(shù)組中的類型對(duì)象將用來(lái)填充泛型類的類型參數(shù),返回填充之后的具體類型。
        為了構(gòu)造一個(gè)Type[],我一開(kāi)始用的方法是System.Array的CreateInstance,但是發(fā)現(xiàn)它在LabVIEW中不能轉(zhuǎn)換成Type[],因此也無(wú)法傳遞給MakeGenericType。最后找到的解決辦法是使用LabVIEW自帶的數(shù)組類型,往里面添加.NET的類型對(duì)象即可,LabVIEW會(huì)自動(dòng)把它轉(zhuǎn)化成Type[],如下圖所示:


        上面的程序最終生成了一個(gè)
        System.Collections.Generic.Dictionary
        的實(shí)例。
        有了一個(gè)類型對(duì)象,如何生成類的實(shí)例?答案是System.Activator。把生成的類型對(duì)象作為參數(shù)傳遞給Activator的靜態(tài)方法CreateInstance,我們即可得到類的實(shí)例,如下圖所示:

        上面的實(shí)驗(yàn)就像一場(chǎng)詩(shī)情畫意的旅行,然而別高興得太早,真正的噩夢(mèng)從現(xiàn)在才開(kāi)始。通過(guò)CreateInstance生成的
        System.Collections.Generic.Dictionary
        的實(shí)例會(huì)被當(dāng)成System.Object,這是由CreateInstance返回值類型決定的。在C#中,我們可以用一個(gè)強(qiáng)制類型轉(zhuǎn)換,把它轉(zhuǎn)換成Dictionary,可是LabVIEW中似乎做不到這一點(diǎn),即使提供了“類型轉(zhuǎn)換”節(jié)點(diǎn),然而并不能作我們需要的轉(zhuǎn)換。
        LabVIEW把我們的Dictionary當(dāng)做Object,我們無(wú)法使用“調(diào)用”節(jié)點(diǎn)來(lái)調(diào)用Dictionary的方法了。這個(gè)問(wèn)題怎么解決?答案就是Reflection,利用類型對(duì)象的GetMethod方法獲取MethodInfo,再通過(guò)MethodInfo的Invoke方法實(shí)現(xiàn)方法的調(diào)用。真正麻煩之處在于,Invoke需要傳入一個(gè)System.Object[],作為調(diào)用方法的參數(shù)。因此,為了調(diào)用方法,我們還需要首先構(gòu)造這個(gè)參數(shù)列表。

        上一頁(yè) 1 2 下一頁(yè)

        關(guān)鍵詞: LabVIEWNET泛型

        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 沁源县| 辽阳市| 麦盖提县| 温州市| 嘉祥县| 高碑店市| 陆川县| 陈巴尔虎旗| 顺平县| 宜昌市| 老河口市| 屏东市| 湘西| 刚察县| 错那县| 杭锦后旗| 武夷山市| 金乡县| 大田县| 政和县| 肥西县| 崇礼县| 毕节市| 贡嘎县| 辰溪县| 陈巴尔虎旗| 墨玉县| 湘潭市| 河北省| 平潭县| 曲水县| 霍邱县| 水城县| 图木舒克市| 内乡县| 惠水县| 类乌齐县| 阿尔山市| 通山县| 苍溪县| 大方县|