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