新聞中心

EEPW首頁 > 測試測量 > 設計應用 > 學習LabVIEW(二)——操作.NET泛型類

學習LabVIEW(二)——操作.NET泛型類

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


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


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


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

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

上一頁 1 2 下一頁

關鍵詞: LabVIEWNET泛型

評論


技術專區(qū)

關閉