[VS2010 Online] var VS dynamic.
What’s var?
在 C# 3.0,有這樣的一個隱含型別- var 。這個型別是屬於強型別(strongly typed),
讓我們看看它是怎麼使用的:
在 Design Time 就可以看到錯誤,這是因為在 Compiler-Time 就會由右方賦予的值去決定變數的型別。
在這裡先給了 10 這個數值,於是 d 這個變數就會被認定屬於 Integer 的型別, 因此接下來再將字串
指定給 d 時,就會出現無法轉換型別的錯誤。
接下來我們作一個實驗來驗證這個想法:
滑鼠在 var 上停留,按下「F12」,這三個變數的型別分別對應到:String、Int32、DateTime。
這證明了 Compiler 在 design time 就會依據值來按斷型別。
What’s Dynamic?
在C# 4.0裡,多了一個新的型別 - dynamic。讓我們先看看下列這張圖:
這裡出現的 Tooltip 說明 dynamic 這個型別會在 runtime 決定其型別(Late-Binding)。
我們依樣畫葫蘆,將數值「10」指定給 d 這個 dynamic 型別變數,然後在 dynamic 上停
留,按下「F12」,此時你會發現,出現了這樣一個視窗:
因為在 Compiler-Time 時,Compiler 還不知道這個變數是屬於哪種型別,
所以在按下F12時,就無法對應到所屬的型別。
接下來,讓我們透過 Reflector 來看 dynamic 是如何實作出來的:
我們首先建立一個 ClassLibrary 專案,寫入下列程式碼:
透過 Reflector,我們可以看到 dynamic 型別被實作成 Object 型別,再加上
DynamicAttribute 類別的處理,這就是 dynamic 型別的關鍵所在。
這樣在 runtime 時化身為 object 型別的方式讓 dynamic 型別可以達成 late-binding 的效果。
dynamic 這個字根本是針對 Compiler 而言,因為它不知道實際物件的型別為何,所以透過CallSite
去收集 Object 物件回傳的結果,以及設定符合給予值的型別。
Dynamic如何用?
看完上述的說明後,我想你應該會知道,下列程式碼是不可行的:
因為 dynamic 型別會被隱含轉換成 Object 型別,這樣會造成在 Runtime 時會有兩個具有相同參數的方法。
所以當Compile時,就會出現下列錯誤訊息;
Type 'ClassLibrary1.MyClass' already defines a member called 'test1' with the same parameter types
看完 Reflector 的程式碼,我想你應該會有個衝動想做一些嘗試:
但是很抱歉的是,當你 Compile 時會報出這樣的錯;
Do not use 'System.Runtime.CompilerServices.DynamicAttribute'. Use the 'dynamic' keyword instead.
這叫我們老實一點,還是乖乖的用 dynamic 型別就好。(這個方式說不定未來可以使用,但是目前仍無法這樣用)
另外,因為 dynamic 的 late-binding 特性,也會造成如下圖的影響,這個在 Design Time 時要特別注意:
dynamic 的實際應用,我想我以一個 Silverlight 4.0 和 Com 物件整合的新功能來做說明:
1. 首先,開啟一個 Silverlight 4.0 的專案,然後加入C:\Program Files\Microsoft SDKs\
Silverlight\v4.0\Libraries\Client 目錄中的 Microsoft.CSharp.dll 檔案。
2. 拖拉一個按鈕到畫面中:
3. 在 Button 的 Click 事件中寫入下列程式碼:
裡面透過 dynamic 型別去處理和 Com 元件的互動。
4. 因為 Silverlight 和 Com 的互動僅限於 OOB(Out of browser)的狀態,所以要把 OOB 設定打勾:
5. 還有一個提升權限的設定要打勾:
6. 執行專案後,將 Silverlight 程式安裝到桌面上,開啟並按下按鈕,Word
檔案就會開啟並且填入值:
補充:
如果你要在Winform & WPF & Console程式上跑,可以透過下列程式碼:
static void Main() { Type xlAppType = Type.GetTypeFromProgID("Word.Application"); dynamic word = Activator.CreateInstance(xlAppType); word.Visible = true; dynamic doc = word.Documents.Add(); string insertText = "Hello Word!"; dynamic range = doc.Range(0, 0); range.Text = insertText; }
dynamic 型別對於某些情況的使用上的確讓人覺得方便,但是還是建議得小心使用。
修煉大會,我們下次見。
如果您有微軟技術開發的問題,可以到MSDN Forum發問。
如果您有微軟IT管理的問題,可以到TechNet Forum發問喔。