<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

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

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


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


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

          上面的實(shí)驗(yàn)就像一場(chǎng)詩(shī)情畫(huà)意的旅行,然而別高興得太早,真正的噩夢(mèng)從現(xiàn)在才開(kāi)始。通過(guò)CreateInstance生成的
          System.Collections.Generic.Dictionary
          的實(shí)例會(huì)被當(dāng)成System.Object,這是由CreateInstance返回值類(lèi)型決定的。在C#中,我們可以用一個(gè)強(qiáng)制類(lèi)型轉(zhuǎn)換,把它轉(zhuǎn)換成Dictionary,可是LabVIEW中似乎做不到這一點(diǎn),即使提供了“類(lèi)型轉(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,利用類(lèi)型對(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ù)專(zhuān)區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();