新聞中心

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

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

作者: 時間:2017-01-09 來源:網(wǎng)絡(luò) 收藏
誤入歧途的一天。昨天晚上我看見http://digital.ni.com/public.nsf/allkb/DC41DCDA972642CF8625787E00732DDD說LabVIEW不支持.NET的泛型,如果要用,可以用C#寫一個包裝類。我就不信邪了,即使LabVIEW的語言層面不支持,我們也可以用.NET框架提供的Reflection的能力來實(shí)現(xiàn)任何我們想要實(shí)現(xiàn)的目標(biāo)吧,用不著大動干戈寫C#代碼。于是我今天就試了試,最后發(fā)現(xiàn),還是寫C#代碼來得比較方便,盡管我們用純LabVIEW實(shí)現(xiàn)了泛型類的操作。
用Reflection這樣的機(jī)制操作泛型類,首先需要對.NET框架的基本對象模型有些了解。.NET的對象模型和CPython的對象模型有許多共通之處,比如,對象實(shí)例會包含一個執(zhí)行類型對象的指針,這就是可以在運(yùn)行時獲取對象類型信息的基石。這里有一個非常重要的概念,就是類型對象,所謂類型對象就是代表類型的對象,這一點(diǎn)和CPython的對象模型簡直不能更像,類型也是對象。知道了這一點(diǎn),問題就好解決了。首先構(gòu)造泛型類填充類型之后的類的對象,再由類對象來生成類實(shí)例。
我們挑選System.Collections.Generic.Dictionary作為實(shí)驗(yàn)對象。這個泛型類我們需要填充兩個類型參數(shù),一個是Key的類型,一個是Value的類型。
首先,獲取沒有填充類型參數(shù)的Dictionary類對象。類對象可以使用
System.Type.GetType("類名")
這種方式獲取。然而,沒有填充類型的Dictionary的名字是什么呢?在頁面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)的類名。類型選擇的時候要注意,如果要用System.String, System.Int32, 以及System.Type這些類型時,要去mscorlib中找,選擇器列出來的項(xiàng)目中沒有這些,如下圖所示:


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


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

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

上一頁 1 2 下一頁

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

評論


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

關(guān)閉