淺談C# 4.0中的動(dòng)態(tài)類型和動(dòng)態(tài)編程
C# 4.0的主題就是動(dòng)態(tài)編程(Dynamic Programming)。雖然C#仍然是一種靜態(tài)語(yǔ)言,但是對(duì)象的意義開(kāi)始變得越來(lái)越“動(dòng)態(tài)”。它們的結(jié)構(gòu)和行為無(wú)法通過(guò)靜態(tài)類型來(lái)捕獲,或者至少編譯器在編譯程序時(shí)無(wú)法得知對(duì)象的結(jié)構(gòu)和行為。
C#引入了一種新的靜態(tài)類型”dynamic”,當(dāng)你擁有了一個(gè)dynamic類型的對(duì)象后,你“對(duì)它做的事情”只會(huì)在運(yùn)行時(shí)進(jìn)行解析。設(shè)想我們擁有這樣兩個(gè)類,分別表示兩種飲料:
public class Coffee public class Juice |
現(xiàn)在,我們就可以用dynamic類型來(lái)表示這兩種飲料。我們寫一個(gè)函數(shù)GetDrink(),根據(jù)用戶不同的選擇返回不同的對(duì)象。
static private Object GetDrink(int i) static void Main(string[] args) |
C#編譯器允許你通過(guò)dynamic對(duì)象調(diào)用任何方法,即使這個(gè)方法根本不存在,編譯器也不會(huì)在編譯的時(shí)候報(bào)編譯錯(cuò)誤。只有在運(yùn)行的時(shí)候,它才會(huì)檢查這個(gè)對(duì)象的實(shí)際類型,并檢查在它上面GetName()是什么意思。動(dòng)態(tài)類型將使得C#可以以更加統(tǒng)一而便利的形式表示下列對(duì)象:
◆ 來(lái)自動(dòng)態(tài)編程語(yǔ)言——如Python或Ruby——的對(duì)象
◆ 通過(guò)IDispatch訪問(wèn)的COM對(duì)象
◆ 通過(guò)反射訪問(wèn)的一般.NET類型
◆ 結(jié)構(gòu)發(fā)生過(guò)變化的對(duì)象——如HTML DOM對(duì)象
當(dāng)我們得到一個(gè)動(dòng)態(tài)類型的對(duì)象時(shí),不管它是來(lái)自COM還是IronPython、HTML DOM還是反射,只需要對(duì)其進(jìn)行操作即可,動(dòng)態(tài)語(yǔ)言運(yùn)行時(shí)(DLR)會(huì)幫我們指出針對(duì)特定的對(duì)象以及這些操作的具體意義。這將給我們的開(kāi)發(fā)帶來(lái)極大的靈活性,并且能夠極大程度上地精簡(jiǎn)我們的代碼。
下面,我們就以一個(gè)具體實(shí)例SilverlightSolution,來(lái)演示C# 4.0中的動(dòng)態(tài)編程是如何簡(jiǎn)化對(duì)Silverlight應(yīng)用程序中HTML DOM對(duì)象的訪問(wèn)的。
1. 安裝Silverlight 2 runtime和SDK
為了運(yùn)行這個(gè)實(shí)例,我們需要安裝Silverlight 2 runtime和SDK。這些都可以從微軟的網(wǎng)站上直接下載:
Silverlight 2 RTW runtime
Silverlight 2 RTW SDK
另外,因?yàn)閂isual Studio 2010跟Silverlight的一些已知的兼容性問(wèn)題,我們還需要一個(gè)擁有管理員權(quán)限的賬號(hào)來(lái)運(yùn)行Visual Studio 2010 CTP。
2. 下載實(shí)例項(xiàng)目SilverlightSolution
為了演示C# 4.0的諸多新特性,微軟通過(guò)MSDN Code Gallery發(fā)布了一個(gè)演示C#新特性的實(shí)例程序包,我們用到的實(shí)例項(xiàng)目SilverlightSolution就在這個(gè)程序包中。我們可以訪問(wèn):
http://code.msdn.microsoft.com/csharpfuture
下載這個(gè)實(shí)例程序包,然后將我們需要的項(xiàng)目SilverlightSolution解壓到C盤根目錄下。
3. 編譯并運(yùn)行實(shí)例項(xiàng)目
我們用管理員身份啟動(dòng)Visual Studio CTP,然后打開(kāi)SilverlightSolution項(xiàng)目,如果一切正常,我們可以得到一個(gè)空的Silverlight程序頁(yè)面:
#p#
4. 添加對(duì)HTML DOM對(duì)象的動(dòng)態(tài)訪問(wèn)
我們?cè)赑age類中添加兩個(gè)dynamic類型的對(duì)象doc和win,分別表示當(dāng)前頁(yè)面和窗口,修改后Page類如下:
public partial class Page : UserControl |
然后,我們修改Page類的函數(shù)btnSearch_Click(),當(dāng)用戶點(diǎn)擊”Get All”按鈕后,更加用戶搜索的內(nèi)容,修改窗口的標(biāo)題。
void btnSearch_Click(object sender, RoutedEventArgs e) |
5. 添加Virtual Earth Jscript控件
打開(kāi)解決方案中的測(cè)試頁(yè)StartPage.htm,在<title>標(biāo)簽的前面添加如下Jave Script代碼,引用Virtual Earth控件:
<script type="text/javascript" src="http://dev.virtualearth.net |
然后,在<body>標(biāo)簽中添加如下代碼,定義地圖控件的位置和大?。?/P>
通過(guò)簡(jiǎn)單的兩步,我們就完成了對(duì)測(cè)試頁(yè)面的修改。接下來(lái)的工作就是通過(guò)C#訪問(wèn)和控制Virtual Earth控件了。
6. 用C#代碼控制Virtual Earth控件
在Page類中添加如下代碼控制Virtual Earth控件,以實(shí)現(xiàn)獲取地圖,添加Pin的功能:
dynamic map = null; void GetMap() void AddPin(Item item) |
憶苦才能思甜。為了體會(huì)動(dòng)態(tài)編程給我們帶來(lái)的便利,我們來(lái)看看在沒(méi)有動(dòng)態(tài)類型的C# 3.0中,AddPin()函數(shù)應(yīng)該如何實(shí)現(xiàn)。如果是在C# 3.0中,我們的doc,win和map 都將是靜態(tài)類型,為了執(zhí)行這些對(duì)象的某些方法,需要進(jìn)行顯式的類型轉(zhuǎn)換,同時(shí),還需要將方法名作為字符串傳遞以實(shí)現(xiàn)方法的調(diào)用。很明顯,C# 3.0中的實(shí)現(xiàn)過(guò)程非常繁瑣,而C# 4.0中的實(shí)現(xiàn)是如此的優(yōu)雅而自然。
void AddPin(Item item) |
最后,我們需要在適當(dāng)?shù)奈恢谜{(diào)用這兩個(gè)函數(shù),以實(shí)現(xiàn)地圖的加載和Pin的添加。在Page類的Init()函數(shù)中添加GetMap()函數(shù)調(diào)用:
public void Init() |
另外,在lstPictures_SelectionChanged()函數(shù)中添加AddPin()函數(shù),當(dāng)用戶選擇的圖片變化后,重新獲取Pin的位置并添加到地圖上:
void lstPictures_SelectionChanged(object sender, SelectionChangedEventArgs e) |
7. 編譯解決方案
到這里為止,我們對(duì)項(xiàng)目的修改就全部完成了。重新編譯整個(gè)解決方案,我們可以看到添加Virtual Earth控件后的頁(yè)面。當(dāng)我們?cè)谧髠?cè)列表中選擇圖片后,Pin會(huì)定位到這幅圖片拍攝的地點(diǎn),當(dāng)我們把鼠標(biāo)移動(dòng)到Pin上時(shí),則會(huì)顯示圖片和更多的相關(guān)信息。
【編輯推薦】