程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C# 4.0中的動態類型和動態編程

C# 4.0中的動態類型和動態編程

編輯:關於C#

隨著WEB開發的大行其道,各種動態語言也借著這股東風,蓬勃發展起來。在軟件開發界,動態語言正 在被越來越多的的人所接受和使用,在CSDN所做的2007年讀者大調查中,動態語言在開發人群中的受關注 程度竟然達到12%。而在 TIOBE的排名中,動態語言竟然占有了前十名中的六個席位(包括PHP、Python、 Perl和 JavaScript,在加上越來越動態的Java和C#)。

“未來屬於動態語言”似乎正在從一個預言成為一個現實。C#自然不會錯過這種技術發展確實,她正 在通過不斷引入新的動態預言的特性,使自己變得越來越美麗“動”人。

C# 4.0的主題就是動態編程(Dynamic Programming)。雖然C#仍然是一種靜態預言,但是對象的意義開 始變得越來越“動態”。它們的結構和行為無法通過靜態類型來捕獲,或者至少編譯器在編譯程序時無法 得知對象的結構和行為。

C#引入了一種新的靜態類型”dynamic”,當你擁有了一個dynamic類型的對象後,你“對它做的事情 ”只會在運行時進行解析。設想我們擁有這樣兩個類,分別表示兩種飲料:

public class Coffee
   {
     public string GetName()
     {
       return "You selected Maxwell coffee.";
     }
   }
   public class Juice
   {
     public string GetName()
     {
       return "You selected orange juice.";
     }
   }

現在,我們就可以用dynamic類型來表示這兩種飲料。我們寫一個函數GetDrink(),更加用戶不同的選 擇返回不同的對象。

static private Object GetDrink(int i)
{
       if (i == 1)
       {
         return new Juice();
       }
       else // default
       {
         return new Coffee();
       }
}
static void Main(string[] args)
{
       Console.WriteLine("Please Select Your Drink: 1 -- Juice; 2 -- Coffee");
       int nDrinkType = Console.Read();
       dynamic drink = GetDrink( nDrinkType );
       Console.WriteLine( drink.GetName() );
}

C#編譯器允許你通過dynamic對象調用任何方法,即使這個方法根本不存在,編譯器也不會在編譯的時 候報編譯錯誤。只有在運行的時候,它才會檢查這個對象的實際類型,並檢查在它上面GetName()是什麼 意思。動態類型將使得C#可以以更加統一而便利的形式范圍下列對象:

•a. 來自動態編程語 言——如Python或Ruby——的對象

•b. 通過IDispatch訪問的COM對象

•c. 通過反射訪問的一般.NET類型

•d. 結構發生過變化的對象—— 如HTML DOM對象

當我們得到一個動態類型的對象時,不管它是來自COM還是IronPython、HTML DOM 還是反射,只需要對其進行操作即可,動態語言運行時(DLR)會幫我們指出針對特定的對象,這些操作的 具體意義。這將給我們的開發帶來極大的靈活性,並且能夠極大程度上地精簡我們的代碼。

下面 ,我們就以一個具體實例SilverlightSolution,來演示C# 4.0中的動態編程是如何簡化對Silverlight應 用程序中HTML DOM對象的訪問的。

1.安裝Silverlight 2運行時和SDK

為了運行這個實例, 我們需要安裝Silverlight 2運行時和SDK。這些都可以從微軟的網站上直接下載:

Silverlight 2 RTW runtime

Silverlight 2 RTW SDK

另外,因為Visual Studio 2010跟Silverlight的一 些已知的兼容性問題,我們還需要一個擁有管理員權限的賬號來運行Visual Studio 2010 CTP。

2.下載實例項目SilverlightSolution

為了演示C# 4.0的諸多新特性,微軟通過MSDN Code Gallery發布了一個演示C#新特性的實例程序包,我們用到的實例項目SilverlightSolution就在這個程序 包中。我們可以訪問:

http://code.msdn.microsoft.com/csharpfuture

下載這個實例程序包,然後將我們需要的項目SilverlightSolution解壓到C盤根目錄下。

3.編譯並運行實例項目

我們用管理員身份啟動Visual Studio CTP,然後打開SilverlightSolution項目,如果一切正常,我 們可以得到一個空的Silverlight程序頁面:

圖1 初始頁面

4.添加對HTML DOM對象的動態訪問

我們在Page類中添加兩個dynamic類型的對象doc和win,分別表示當前頁面和窗口,修改後Page類如下 :

public partial class Page : UserControl
     {
     // 添加的代碼
       dynamic doc = HtmlPage.Document.AsDynamic();
       dynamic win = HtmlPage.Window.AsDynamic();
     //…
}

然後,我們修改Page類的函數btnSearch_Click(),當用戶點擊”Get All”按鈕後,更加用戶搜索的 內容,修改窗口的標題。

void btnSearch_Click(object sender, RoutedEventArgs e)
     {
         doc.Title = "Pictures of " + txtTag.Text;
         lstPictures.ItemsSource = Source.LoadItems();
     }

5.添加Virtual Earth Jscript控件

打開解決方案中的測試頁StartPage.htm,在<title>標簽的前面添加如下Jave Script代碼,引 用Virtual Earth控件:

<script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1"/>

然後,在<body>標簽中添加如下代碼,定義地圖控件的位置和大小:

<div id='myMap' style="position:absolute; top:40px; left:200px; width:550px; height:400px;"/>

通過簡單的兩步,我們就完成了對測試頁面的修改。接下來的工作就是通過C#訪問和控制Virtual Earth控件了。

6.用C#代碼控制Virtual Earth控件

在Page類中添加如下代碼控制Virtual Earth控件,以實現獲取地圖,添加Pin的功能:

dynamic map = null;
     void GetMap()
     {
         map = win.New.VEMap("myMap");
         map.LoadMap();
     }
     void AddPin(Item item)
     {
         dynamic loc = win.New.VELatLong(item.Latitude, item.Longitude);
         var pin = map.AddPushpin(loc);
         pin.SetTitle(item.Title);
         pin.SetDescription(item.Description);
         map.SetCenterAndZoom(loc, 7);
     }

憶苦才能思甜。為了體會動態編程給我們帶來的便利,我們來看看在沒有動態類型的C# 3.0中, AddPin()函數應該如何實現。如果是在C# 3.0中,我們的doc,win和map 都將是靜態類型,為了執行這些 對象的某些方法,需要進行顯式的類型轉換,同時,還需要將方法名作為字符串傳遞以實現方法的調用。 很明顯,C# 3.0中的實現過程非常繁瑣,而C# 4.0中的實現是如此的優雅而自然。

void AddPin(Item item)
  {
ScriptObject loc = win.CreateInstance("VELatLong", item.Latitude, item.Longitude);
ScriptObject pin = (ScriptObject)map.Invoke("AddPushpin", loc);
pin.Invoke("SetTitle", item.Title);
pin.Invoke("SetDescription", item.Description);
map.Invoke("SetCenterAndZoom", loc, 7);
}

最後,我們需要在適當的位置調用這兩個函數,以實現地圖的加載和Pin的添加。在Page類的Init()函 數中添加GetMap()函數調用:

public void Init()
{
      GetMap();
}

另外,在lstPictures_SelectionChanged()函數中添加AddPin()函數,當用戶選擇的圖片變化後,重 新獲取Pin的位置並添加到地圖上:

void lstPictures_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
      Item selected = lstPictures.SelectedItem as Item;
      AddPin(selected);
}

7.編譯解決方案

到這裡為止,我們對項目的修改就全部完成了。重新編譯整個解決方案,我們可以看到添加Virtual Earth控件後的頁面。當我們在左側列表中選擇圖片後,Pin會定位到這幅圖片拍攝的地點,當我們把鼠標 移動到Pin上時,則會顯示圖片和更多的相關信息。

圖2 添加Virtual Earth控件後的頁面

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved