在Visual Studio 2010中使用C# 4.0的動態類型
原創【51CTO譯文精選】C# 4.0包括大量的增強和新增特性,包括:
1、支持動態查找
2、同時支持命名參數和可選參數
3、增強的COM互操作特性
4、支持方差
本文將只對前面兩項做一些介紹,并提供一些實例,讓你充分了解如果在你的應用程序中利用這些特性將會得到什么好處,后面兩項將在未來的文章的進行闡述。
有些C#新特性被合并到微軟新的動態語言運行庫(DLR)環境中去了,動態語言運行庫是.Net框架中的新特性,它可以和靜態語言進行互操作。
51CTO編輯推薦專題《Visual Studio 2010應用與開發》
注意:如果你想親自運行一下本文給出的實例,你需要安裝Visual Studio 2010 Beta 1或更高版本。Visual Studio 2010 Beta版于今年5月中旬與.NET 4.0一起發布。
理解DLR
DLR是構建在通用語言運行庫(CLR)基礎之上的,動態類型語言如Python,Ruby和JavaScript可以和大家熟悉的靜態.Net語言C#,托管C++,以及VB共存,CLR為靜態語言(如C#和VB)入駐和互操作提供通用平臺,而DLR位于CLR之上,為動態語言入駐和互操作提供通用平臺。
DLR增加了一套服務,使得在.Net托管平臺上實施動態語言更加容易,這些服務包括支持動態類型系統,標準的主機托管模式,以及快速生成動態代碼。此外,DLR還讓動態語言和靜態語言之間實現了雙向互操作。
為了支持DLR,.Net框架4.0中特地增加了一個System.Dynamic命名空間,動態語言運行庫包括三層,如圖1所示:
圖- 1 DLR的組件:DLR包括.Net語言集成層,一套運行庫代碼組件和語言聯編程序
1、.Net語言集成層
2、動態語言運行庫代碼組件
3、語言聯編程序
DLR提供的服務包括:
1、動態方法調度
2、動態代碼生成
3、托管API
DLR就簡要介紹這些了,繼續前進看看C#的新特性。
動態查找
引入動態類型后,從方法或表達式返回值時,你就再也不用擔心對象的類型了,運行庫根據返回值的類型執行必要的聯編。
靜態和動態類型
靜態語言如C#,C++,Java都是在編譯時執行類型檢查,與此相反,動態語言如JavaScript,Perl和Ruby都是在運行時執行類型檢查。C#最初被設計為基于強壯類型的語言,因為編譯器可以確保類型匹配,在開發周期的早期階段就會發現bug。現在情況發生了變化,在C#中引入了動態類型,你可以無縫地調用不同類型的對象了,如COM和JavaScript。
Var和dynamic關鍵字
為了支持動態變量聲明,C# 4.0引入了關鍵字dynamic,在C#中var和dynamic關鍵字提供了本地類型含義,你不需要在賦值運算符左邊指定數據類型,系統會動態綁定正確的類型。但與dynamic關鍵字不同的是,使用var時,你必須在賦值運算符的右邊指定類型。使用dynamic關鍵字時,你不用指定任何類型,所有類型綁定都在運行時完成。
動態類型示例
光聽似乎理解起來有點難度,我們還是來看看實際的例子吧,仔細研究以下三個業務邏輯類,以及每個類中包含的方法:
- class ProductBL
- {
- public void ProcessNewProductData()
- {
- Console.WriteLine("Process method of the ProductBL " +
- "class has been called.");
- }
- }
- class OrderBL
- {
- public void ProcessNewOrderData()
- {
- Console.WriteLine("Process method of the OrderBL " +
- "class has been called.");
- }
- }
- class CustomerBL
- {
- public void ProcessNewCustomerData()
- {
- Console.WriteLine("Process method of the CustomerBL " +
- "class has been called.");
- }
- }
正如你所看到的,每個類都有不同的方法,假設在運行過程中,你需要調用process方法,這類問題使用動態類型就很好解決,首先,創建一個包含一系列業務邏輯實例類型的enum。
- public enum BusinessLogicObjectType {
- ProductBL, CustomerBL, OrderBL };
下面的方法返回業務邏輯類的一個實例:
- public static object GetBusinesLogicInstance(
- BusinessLogicObjectType businessLogicObjectType)
- {
- switch (businessLogicObjectType)
- {
- case BusinessLogicObjectType.ProductBL:
- return new ProductBL();
- case BusinessLogicObjectType.CustomerBL:
- return new CustomerBL();
- default: return null;
- }
- }
現在你就可以使用dynamic關鍵字,在運行過程中調用合適的業務邏輯實例,如下所示:
- static void Main(string[] args)
- {
- dynamic dynamicBLObject = GetBusinesLogicInstance(
- BusinessLogicObjectType.ProductBL);
- dynamicBLObject.ProcessNewProductData();
- Console.Read();
- }
就這么簡單。
#p#
如圖2所示,執行這個應用程序時會顯示一條消息“ProductBL類的process方法已經被調用”,在清單1中你可以看到完整的示例代碼。
圖- 2 示例輸出:這是動態調用業務對象類方法的輸出
清單1 Dynamic關鍵字
- using System;
- namespace NewCSharpFeatures
- {
- public enum BusinessLogicObjectType { ProductBL, CustomerBL, OrderBL };
- class ProductBL
- {
- public void ProcessNewProductData()
- {
- Console.WriteLine("Process method of the ProductBL " +
- "class has been called.");
- }
- }
- class OrderBL
- {
- public void ProcessNewOrderData()
- {
- Console.WriteLine("Process method of the OrderBL " +
- "class has been called.");
- }
- }
- class CustomerBL
- {
- public void ProcessNewCustomerData()
- {
- Console.WriteLine("Process method of the CustomerBL " +
- "class has been called.");
- }
- }
- class Program
- {
- public static object GetBusinesLogicInstance(
- BusinessLogicObjectType businessLogicObjectType)
- {
- switch (businessLogicObjectType)
- {
- case BusinessLogicObjectType.ProductBL: return new ProductBL();
- case BusinessLogicObjectType.CustomerBL: return new CustomerBL();
- default: return null;
- }
- }
- static void Main(string[] args)
- {
- dynamic dynamicBLObject = GetBusinesLogicInstance(
- BusinessLogicObjectType.ProductBL);
- dynamicBLObject.ProcessNewProductData();
- Console.Read();
- }
- }
- }
命名參數和可選參數
可選參數,默認值和命名參數是更有趣的新增特性,可選參數讓你可以避免在調用方法時必須傳遞參數,默認值讓你在調用方法不用傳輸參數時指定其默認值,命名參數讓你可以使用參數名字作為參數,而不用提供它們在參數列表中的位置,意思是你可以不按順序向方法提供參數。還是來看看實際的例子吧。
看看下面這個方法:
- static int Add(int x = 0, int y = 0)
- {
- return (x + y);
- }
正如你所看到的,參數x和y都有了默認值,add()方法使用它的參數列表進行了默認的初始化,現在你可以不用傳遞任何參數調用add()方法,如:
- int result = Add();
上面這行代碼會返回0,因為這兩個參數都使用了其默認值0,當然,你也可以明確地傳遞參數給這個方法,如:
- int result = Add(5, 6); // 返回11
可選參數應該顯示在方法參數列表的末尾,換句話說就是,可選參數應該最后出現,應該先指定前面的所有需要的參數,因此,下面的方法是無效的:
- static int Add(int x = 0, int y)
- {
- return (x + y);
- }
如果你編譯這段代碼,將會遇到錯誤“可選參數必須出現在所有需要的參數的后面”。
現在你也可以使用命名參數傳遞值了,這樣就不用記住參數的順序了,如:
- int result = Add( y:6, x:5); //返回11
注意前面這行代碼是先指定的y,后指定的x,這與add()方法中的參數定義順序是相反的。
小結
C# 4.0中新增的最重要的特性是dynamic關鍵字,它讓你在編譯時創建對象類型,即使你不知道對象類型是什么也行。關于C# 4.0更多的新特性和示例代碼,你可以去MSDN看看。
原文:Explore C# 4's New Dynamic Types and Named/Optional Parameters
作者:Joydip Kanjilal
【編輯推薦】